Just a fairly easy question that cant seem to work for me.
is it possible to use cakePHP's saveMany() to save an array of arrays.
case example:
if you have a csv file with many columns and rows.in my case calling saveMany inside a foreach loop only saves the first row of the csv file and stops.
i thougth it should do save row after row but seems i was wrong.
Is there an easier way to do this still in cakephp?
Yes, you can use saveMany() to save multiple of the same model at one time. You have to format the data carefully, or else it won't work:
$data = array(
0 => array(
'Model' => array(
'field1' => 1,
'field2' => 2,
),
),
1 => array(
'Model' => array(
'field1' => 1,
'field2' => 2,
),
),
);
Or you can leave out the 'Model' like so:
$data = array(
0 => array(
'field1' => 1,
'field2' => 2,
),
1 => array(
'field1' => 1,
'field2' => 2,
),
);
See the cookbook about SaveMany: http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-savemany-array-data-null-array-options-array
Related
I have few tables which are connected (hasMany) like a tree: 1 -> 2 -> 3.
There are few records in table 1, table 2 and 3.
I'm using CakePHP to fetch all data from table 1 with connected table 2, which is connected with table 3.
However few records in table 1 don't have any connected records in table 2. The same is in table 2, some records don't have connected records in table 3.
For the second situation scripts work fine. I get something like this:
1 -> 2 -> empty. But in the first situation, when data looks similar to: 1-> empty -> empty I get errors that table 3 doesn't exist.
Is there any solution to skip this errors and get pretty formatted association table as return to my query?
$options = array(
'conditions' => array(
'Table1.id' => $table1_ids
),
'contain' => array(
'Table2' => array(
'conditions' => array(
'id' => $table2_ids
),
'Table3' => array(
'conditions' => array(
'date_end >' => date('Y-m-d H:i:s')
),
'fields' => array('id'),
),
'fields' => array()
),
),
'fields' => array('id', 'name')
);
$this->Table1->recursive = -1;
$table1 = $this->Table1->find('all', $options);
It's not really cakephp to blame here but your lack of understanding what contain does.
What you're looking for are left joins, which is actually hinted in the documentation of contain.
i have a table in which i want to get only two columns data .. right now i am using findAll method ... i don't know how can I get the specific two fields data in CakePHP
$recentContacts = $this->Contact->find('all',
array(
'order'=>'Contact.idContacts DESC',
'limit' => 6,
'conditions' => array(
'Contact.User_id' => $id)));
in my contacts table there are two fields one is "name" and other is "number"
which I want to extract ...
You can do this by adding fields attribute.
$recentContacts = $this->Contact->find('all',
array
(
'order'=> array( 'Contact.id' , 'Contacts DESC'),
'limit' => 6,
'fields' => array(
'Contact.name',
'Contact.number'
),
'conditions' => array
(
'Contact.User_id' => $id
)
));
you can use like this way with your same code to add fields
$recentContacts = $this->Contact->find('all',
array(
'order'=>'Contact.idContacts DESC',
'limit' => 6,
'fields' => array(
'Contact.name',
'Contact.number'
),
'conditions' => array(
'Contact.User_id' => $id)));
in previous answer they have changed you id instead of idContacts, you can just copy my code and solve your problem.
let me know if i can help you more.
I'm stuck with something fairly simple:
SN hasMany NA. I retrieve data, with a condition on the contained NAs using
$this->find('all',array(
'recursive' => -1,
'conditions' => array(
'SN.deleted IS NULL',
'SN.user_id' => $user_id,
),
'contain' => array(
'NA' => array('conditions'=> array('wave' => 1) ),
)
));
Both SN and NA act as Containable.
I get the data, but NA is not nested in the SN array:
array(
(int) 0 => array(
'SN' => array(
'id' => '1',
'user_id' => '1',
),
'NA' => array(
(int) 0 => array(
'id' => '1',
'SN_id' => '1',
'wave' => '1',
)
)
),
This results in a lot of annoying behaviour using the FormHelper (which I fix at the moment by massaging the data for my needs, but I'd still like to understand what I am doing wrong), e.g. with the data returned from Containable, I can't specify the path.
debug($this->data[$s]['NA'][0]['wave']); # would work
echo $this->Form->input("$s.NA.0.role"); # doesn't work
# leads to data[SN][0][NA][0][role] # SN is auto-prepended
echo $this->Form->input("$s.SA.NA.0.role"); # what I use after massaging the data so it's nested
I still have problems with validation messages not showing up where they're supposed, even though I tried both massaging the data and the error message arrays.
I am trying to get an array structure of a database and a few of its fields from my controller.
The fields I want are: Document.id, Document.name, Document.submission_date, and the Requester.name which is joined with: Requester.id = Document.requester_id
In my Controller:
Method A:
$documents = $this->Document->find('list', array('fields' => array('Document.name', 'Requester.name', 'Document.submission_date')));
Can't seem to find 'Requester.name'
Method B:
$documents = $this->Document->find('list', array('fields' => array('Document.name', 'Requester.name', 'Document.submission_date'), 'recursive' => 0));
Gives me:
array(
'2012-08-17' => array(
'Document_A' => 'Requester_Z'
),
'2012-08-05' => array(
'Document_B' => 'Requester_Y'
),
'2012-07-09' => array(
'Document_C' => 'Requester_X'
)
)
But I need it to be in format:
array(
(int) 0 => array(
'id' => '16'
'submission_date' => '2012-08-17'
'name' => 'Document_A',
'requester_name' => 'Requester_Z'
),
(int) 1 => array(
'id' => '41'
'submission_date' => '2012-08-05'
'name' => 'Document_B',
'requester_name' => 'Requester_Y'
),
(int) 2 => array(
'id' => '213'
'submission_date' => '2012-07-09'
'name' => 'Document_C',
'requester_name' => 'Requester_X'
),
)
I can't seem to figure it out after going through the 2.0 CakeBook and on StackOverflow...
Any help would be appreciated? Sorry - I'm still a n00b with CakePHP (but REALLY loving it so far!) Thanks!
You need to do a find('all') instead of a find('list') and you can use the fields key like you already are to limit the amount of info that's returned.
It won't come back exactly as you need the data, each field will be in a key of the model it belongs to - if you really need it in that format you can get away with using a virtual field, a custom find, or an afterFind callback to modify the data.
Find list is generally for an id => label formatted array.
You can try this:
$documents = $this
->Document-
>find('all',
array(
'fields' => array('Document.name', 'Requester.name', 'Document.submission_date'),
'joins' => array(
'table' => 'requesters',
'alias' => 'Requester',
'type' => 'left',
'conditions' => array('Requester.id = Document.requester_id')
)
)
);
I have a query that I am running through paginate. This query contains a model ("PaymentException") that has an afterfind method that tacks on a copy of the last "ExceptionWorkflowLog", and calls it "LastWorkflowLog".
The query being passed to paginate:
$this->paginate = array(
'fields' => array(
'PaymentException.*', 'Procedure.id', 'Procedure.cpt',
'Procedure.expected_amount', 'Procedure.allowed_amount', 'Procedure.difference_amount',
'Claim.id', 'Claim.number', 'Payer.abbr'
),
'limit' => 50,
'joins' => array(
array(
'table' => 'procedures',
'alias' => 'Procedure',
'conditions' => array('Procedure.id = PaymentException.procedure_id')
),
array(
'table' => 'claims',
'alias' => 'Claim',
'conditions' => array('Claim.id = Procedure.claim_id')
),
array(
'table' => 'payers',
'alias' => 'Payer',
'conditions' => array('Payer.id = Procedure.payer_id')
),
array(
'table' => 'groups',
'alias' => 'Groups',
'conditions' => array('Groups.id = Claim.group_id')
)
),
'conditions' => $conditions,
'contain' => array('ExceptionWorkflowLog')
);
The resulting array (from the query that combines both "PaymentException", "ExceptionWorkflowLog", and "LastWorkflowLog") looks like below:
0 =>
'PaymentException' => array(fields and values),
'ExceptionWorkflowLog' => array(of ExceptionWorkflowLogs),
'LastWorkflowLog' => array(fields and values of the last indexed ExceptionWorkflowLog)
1 => ...
ExceptionWorkflowLog is mapped to PaymentException by PaymentException.id. It's a many to one relationship (thus the array of results under the ExceptionWorkflowLog).
I would like to use paginate to sort on the "updated" field on either the last indexed ExceptionWorkflowLog or the LastWorkflowLog.
Is there a way to do this with paginate? Currently, if I set the table heading to point to "LastWorkflowLog.updated", the query returns false because the query doesn't know what "LastWorkflowLog" is.
Since this has a couple hundred views, I figured I'd come back and post what I did. CakePHP's handling of joins is absolutely terrible. I rewrote the query to not use joins, but use contains. That seems to have solved it. I feel dirty.