Associated model is not fetched in CakePHP find - cakephp

I am experiencing an odd behaviour:
In the $results['capital'] each contained model is fetched (therefore, CapitalCategory, CapitalCategory->Category and Picture) for the Capital model.
But in the $results['category'] the Picture model is not fetched (only Capital and Category are fetched) for the CapitalCategory model.
I have attached a screenshot for clarity:
What could be the problem? Where should I look? Thank you!
EDIT
Here is the output for the $results['capital'] array,
[0] => Array
(
[Capital] => Array
(
[name] => N'Djamena
[id] => 81
)
[CapitalCategory] => Array
(
[0] => Array
(
[value] => Ciad
[category_id] => 2
[capital_id] => 81
[Category] => Array
(
[name] => Ţară
)
)
)
[Picture] => Array
(
[0] => Array
(
[picture] => http://farm2.static.flickr.com/1270/879755600_126f8824db_s.jpg
[capital_id] => 81
)
)
)
and here is the output for the $results['category'] array (I've put only one record since they are similar):
[0] => Array
(
[CapitalCategory] => Array
(
[value] => America de Sud
)
[Capital] => Array
(
[name] => Asuncion
[id] => 56
)
[Category] => Array
(
[name] => Continent
[id] => 1
)
)

It looks like the problem was that CakePHP expects to have all foreign keys in the fields array. Therefore, after I have added the 'CapitalCategory.capital_id' in the fields array, the Pictures are shown. Still don't get why the first query worked while this one not, but I'm glad I figured it out.

Related

cakephp multiple records data array fit in request data

I need to get multiple records from model, then put them into request->data for a view to render into a form with multiple input fieldsets for example name='data[Applicant][0][display_name]'. name='data[Applicant][1][display_name]'...data value goes in for each applicant.
Actually I've already done what i want, but i do not think it is a good method to do so.
Appreciate if anyone can guide me
foreach ($this->Applicant->data['Applicant'] as $key=>$item){
$data['Applicant'][] = $item['Applicant'];
}
$this->request->data = $data;//set Model to data
$this->set('data' , $this->Applicant->data);
$this->Applicant->data is the following:
Array
(
[Applicant] => Array
(
[0] => Array
(
[Applicant] => Array
(
[id] => 1
[application_id] => 17
[name] => User
[first_name] =>
...
)
)
[1] => Array
(
[Applicant] => Array
(
[id] => 3
[application_id] => 17
[name] =>
[first_name] =>
the following is the desired output (less one level):
Array
(
[Applicant] => Array
(
[0] => Array
(
[id] => 1
[application_id] => 17
[name] => User
[first_name] =>
...
)
[1] => Array
(
[id] => 3
[application_id] => 17
[name] =>
[first_name] =>
thanks
This should suffice:
$this->request->data['Applicant'] = Hash::extract( $this->Applicant->data, 'Applicant.{n}.Applicant' );

Extracting Cakephp Multidimensional arrays

I need to find all the records from an array of id ( $user_id = array(); ) to be saved into a table of notifications, to tell these users that their accounts are activated.
After executed these,
$x = $this->User->find('all',array('conditions'=>array('User.id'=>$user_id)));
$find = Set::extract('/User', $x);
I get this result:
Array(
[0] => Array
(
[User] => Array
(
[id] => 2
[name] => joe
[age] => 13
[class] => D
)
)
[1] => Array
(
[User] => Array
(
[id] => 3
[name] => lambert
[age] => 14
[class] => E
)
)
)
I need to achive the array below by extracting the one above
Array
{
[id] => 2
[name] => joe
[age] => 13
[class] => D
}
Array
{
[id] => 3
[name] => lambert
[age] => 14
[class] => E
}
How to make this happen using CakePHP?
Then, inside my view, how to send multiple records based on the extracted array above?
Is it possible to make a foreach loop inside view?
echo $html->link(__('Send',true),array('controller'=>'users','action'=>'notifications',$user_id),array('class'=>'button'));
Obviously, putting the link inside the loop will result in two links with different ids ($user_id = 2 and $user_id = 3). I don't want that to happen. I want a single link that will submit these ids in one go.
The answer for your first question
$data_final =array();
foreach($findas $d)
{
$data_final[] =$d['User'];
}
then you wil achive
Array
(
[0] => Array
(
[id] => 2
[name] => joe
[age] => 13
[class] => D
)
[1] => Array
(
[id] => 4
[name] => lamber
[age] => 23
[class] => E
)
)
The answer to second question
the way you are doing with url is not a good practice. you should post the records

CakePHP find screwed up

I have a simple database table which looks like this: http://www.xup.in/dl,17431410/screwed.jpg/ Now I want the data using $this->find('all') in the ItemModel which looks like:
public function getList() {
$data = $this->find('all');
pr($data);
exit;
}
The output is
Array
(
[0] => Array
(
[Champion] => Array
(
[id] => 1
[name] => A
[key] => ahri
)
)
[1] => Array
(
[Champion] => Array
(
[id] => 2
[name] => A
[key] => akali
)
)
[2] => Array
(
[Champion] => Array
(
[id] => 3
[name] => A
[key] => alistar
)
)
[3] => Array
(
[Champion] => Array
(
[id] => 4
[name] => A
[key] => amumu
)
)
)
I have absolutely no idea why the name is cut at the first letter.
schema looks good to me.
did you clear the cache? the old scheme that is cached in /tmp/cache/persistent might still have something else stored.
maybe a tinyint, or char 1 etc.

saveAll() on nested data

When I try to create a new entry of Template with the $data array, the models of Template, Group and Product are saved correctly. But the nested Calcfield (which is a hasMany of Group) is not saved. :( Group and Product are hasMany of Template.
Is this possible at all?
$this->Template->create();
$this->Template->saveAll($data, array('validate' => false));
// $data looks like this:
Array
(
[Template] => Array
(
[title] =>
[shorttitle] => Wie auch immer
[place] => Hannover
[size] =>
)
[Group] => Array
(
[0] => Array
(
[title] => Hosting
[order] =>
[Calcfield] => Array
(
[0] => Array
(
[title] => Hosting
[value] => 0
[description] =>
)
[1] => Array
(
[title] => Strom
[value] => 0
[description] =>
)
)
)
)
[Product] => Array
(
[0] => Array
(
[share] => 10
[businessunit] => Marketing
)
[1] => Array
(
[share] => 30
[businessunit] => intl. CRM
)
)
)
No, recursive saves are not possible, as far as I know. You would need to stick those in a separate array and then save them after the initial save.
Since CakePHP 2.1 it's possible to save deeply-nested models using the deep parameter in saveAll (since CakePHP 2.1)
ref. http://book.cakephp.org/2.0/en/models/saving-your-data.html?highlight=saveall#model-saveassociated

Cakephp how to use Set Class to make an assoc array?

I have the output array from a $Model->find() query which also pulls data from a hasMany relationship:
Array(
[Parent] => Array
(
[id] => 1
)
[Child] => Array
(
[0] => Array
(
[id] => aaa
[score] => 3
[src] => stage6/tn~4bbb38cc-0018-49bf-96a9-11a0f67883f5.jpg
[parent_id] => 1
)
[1] => Array
(
[id] => bbb
[score] => 5
[src] => stage0/tn~4bbb38cc-00ac-4b25-b074-11a0f67883f5.jpg
[parent_id] => 1
)
[2] => Array
(
[id] => ccc
[score] => 2
[src] => stage4/tn~4bbb38cc-01c8-44bd-b71d-11a0f67883f5.jpg
[parent_id] => 1
)
)
)
I'd like to transform this output into something like this, where the child id is the key to additional child attributes:
Array(
[aaa] => Array
(
[score] => 3
[src] => stage6/tn~4bbb38cc-0018-49bf-96a9-11a0f67883f5.jpg
)
[bbb] => Array
(
[score] => 5
[src] => stage0/tn~4bbb38cc-00ac-4b25-b074-11a0f67883f5.jpg
)
[ccc] => Array
(
[score] => 2
[src] => stage4/tn~4bbb38cc-01c8-44bd-b71d-11a0f67883f5.jpg
)
}
Is there an easy way to use Set::extract, Set::combine, Set::insert, etc. to do this efficiently? I cannot figure it out.
I've used Set::combine to do this a few times, but I can't make an argument for efficiency. As an example, I had a list of volunteers and each of those volunteers belonged to a group. I wanted to retrieve each committee and its volunteers, but as an associative array keyed by the committee name. Here's the code I used to do that:
$volunteers = Set::combine (
$this->Volunteer->Committee->find (
'all',
array ( 'order' => 'display_order' )
),
'{n}.Committee.title',
'{n}.Volunteer'
);
Hopefully that helps. The documentation for Set::combine may help elaborate on the details.
As Rob says, Set::combine is the answer to your question. Here's a sample solution, using the XPath 2.0 syntax:
$parents = $this->Parent->find('all');
$assocChildren = Set::combine( $parents, '/Child/id', '/Child' );

Resources