Cakephp: How to get data with specific fields on associated model - php

I'm using cakephp framework. I have two tables on my DB, courses and modules table. Those tables are related, courses has many modules. Basically I want to get data on courses and on modules but with specific fields. I want to get just the id and the title of the course and the id and the title of the module.
This code:
$courses_taken = $this->Course->find('all', array(
'conditions' => array('Course.id' => $course_id_list),
'fields' => array('Course.id', 'Course.title')
));
gives me:
array(
(int) 0 => array(
'Course' => array(
'id' => '1',
'title' => 'course 1'
),
'Module' => array(
(int) 0 => array(
'id' => '1',
'course_id' => '1',
'title' => 'module 1',
'image' => null,
'content' => 'Lorem ipsum',
'voice_over' => null,
'created' => '2014-09-03 14:02:25',
'modified' => '2014-09-03 14:02:28'
),
(int) 1 => array(
'id' => '2',
'course_id' => '1',
'title' => 'module 2',
'image' => null,
'content' => 'Sasdas',
'voice_over' => null,
'created' => null,
'modified' => null
)
)
),
(int) 1 => array(
'Course' => array(
'id' => '2',
'title' => 'course 2'
),
'Module' => array()
)
)
But I wanna select a specific field for module as well so I tried this code:
$courses_taken = $this->Course->find('all', array(
'conditions' => array('Course.id' => $course_id_list),
'fields' => array('Course.id', 'Course.title', 'Module.id', 'Module.title')
));
but gives me an error: Column not found: 1054 Unknown column 'Module.id' in 'field list'.
Please help me guys thanks.

Got the answer, To make sgt's answer work, $actsAs property should be added in Course model. Reference : http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html

Either you use some behavior like Containable and your find() will look like this :
$courses_taken = $this->Course->find('all', array(
'conditions' => array('Course.id' => $course_id_list),
'fields' => array('Course.id', 'Course.title'),
'contain' => array(
'Module' => array(
'fields' => array('Module.id', 'Module.title'),
),
),
));

try this -
$courses_taken = $this->Course->find('all', array(
'conditions' => array('Course.id' => $course_id_list),
'fields' => array('Course.id', 'Course.title'),
'contain' => array('Module.id', 'Module.title')
));

Related

cant join tables HABTM and many to one ,cakephp

I cant use a join to get the required data from the table relationship of
Student HABTM Subject, and
Guardian 1 to many Student
Without giving all the code,my find gets the required data but it adds another table (AvailabilityForStudent)which has a HABTM relationship with Student, along with other fields. I simply get too much data.
I have to add Guardian2 to the Guardian table to avoid a conflict which i dont understand.
What is the correct join to display data from 3 tables only?
$students = $this->find('all', array(
'joins'=>$joins,
'conditions' => $conditions,
'fields'=> $fields,
'order'=>$order,
));
$joins = array(
array('table' => 'students_subjects',
'alias' => 'StudentsSubject',
'type' => 'LEFT',
'conditions' => array(
'Student.id=StudentsSubject.student_id',
)
),
array('table' => 'subjects',
'alias' => 'Subject',
'type' => 'LEFT',
'conditions' => array(
'StudentsSubject.subject_id=Subject.id',
)
),
array('table' => 'guardians',
'alias' => 'Guardian2',
'type' => 'LEFT',
'conditions' => array(
'Student.guardian_id=Guardian2.id',
)
),
);
(int) 0 => array(
'Student' => array(
'id' => '267',
'last_name' => 'xxx',
'first_name' => 'xxx',
'address_suburb' => 'xxx',
'student_inactive' => false,
'student_mobile' => '0'
),
'Guardian' => array(
'guardian_last_name' => 'xx',
'guardian_first_name' => 'xxxx',
'id' => '267',
'guardian_mobile' => 'xxxx',
'guardian_email' => 'xx#yahoo.com.au'
),
'Subject' => array(
'name' => 'English: Year 7 - 10',
(int) 0 => array(
'id' => '9',
'name' => 'English: Year 7 - 10',
'StudentsSubject' => array(
'id' => '1079',
'student_id' => '267',
'subject_id' => '9',
'created' => null,
'modified' => null
)
)
),
'StudentsSubject' => array(
'id' => '1079'
),
'AvailabilityForStudent' => array(
(int) 0 => array(
Update- added this line $this->recursive = -1 instead of $this->Student->recursive = -1; and it works
Update- added this line $this->recursive = -1 instead of $this->Student->recursive = -1; and it works

cant paginate with containable

In cakephp I can't get paginate to work with containable.
I followed the docs and I can't get it to work with just 2 tables. Instead I get every associated table.
I get this error as well:
Notice (8): Indirect modification of overloaded property StudentsController::$paginate has no effect
The code works fine with a find all.
http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html#using-containable
$this->Student->Behaviors->load('Containable');
$this->paginate['Student'] = array(
'conditions' => array( 'student_inactive' => false,'Student.student_enq' => true ),
'limit'=>10,
'fields' => array('Student.id,last_name,first_name') ,
'contain' => array('Guardian' => array(
'fields' => array('id', 'guardian_email', 'guardian_first_name', 'guardian_last_name' ))) ,
'order' => 'Student.id'
);
$st = $this->paginate('Student');
array(
(int) 0 => array(
'Student' => array(
'id' => '233',
'student_inactive' => false,
'student_enq' => false,
'student_unallocated' => false,
'first_name' => 'Aadil',
.....
),
'TutoringType' => array(
'id' => '1',
'value' => 'Individual Tuition'
),
'Referral' => array(
'id' => '1',
'title' => 'Google - Organic',
'details' => ''
),
Try with -
$this->Paginator->settings = array(
'conditions' => array( 'student_inactive' => false,'Student.student_enq' => true ),
'limit'=>10,
'fields' => array('Student.id,last_name,first_name') ,
'contain' => array('Guardian' => array(
'fields' => array('id', 'guardian_email', 'guardian_first_name', 'guardian_last_name' ))) ,
'order' => 'Student.id'
);
$st = $this->Paginator->paginate('Student');

Order multidimentional array with cakephp find all

I have Story related to a Chapter with a many to many relation
I have a StoryChapter Model .
I have this find all stories result :
array(
(int) 0 => array(
'Story' => array(
'id' => '111',
'title' => 'First Story',
'question' => 'What do you want ?',
'description' => 'ezrsrfgq ergtqergq',
'date' => '2014-06-10',
'image' => '/uploads/stories/111.jpg',
'created' => '2014-06-10 07:51:35',
'modified' => '2014-06-13 12:45:43',
'created_by' => '1',
'original' => null,
'tags' => ''
),
'StoryChapter' => array(
(int) 0 => array(
'id' => '110',
'story_id' => '111',
'chapter_id' => '81',
'chapter_title' => 'Second Chapter',
'created' => '2014-06-11 00:00:00'
),
(int) 1 => array(
'id' => '109',
'story_id' => '111',
'chapter_id' => '80',
'chapter_title' => 'First Chapter',
'created' => '2014-06-13 00:00:00'
)
),
'StoryUser' => array(),
'StoryGroup' => array(),
'Favorite' => array(),
'Tag' => array()
),
(int) 1 => array(
'Story' => array(
'id' => '112',
'title' => 'Second Story',
'question' => 'What do you want ?',
'description' => 'edghs rthsghsx ghs rhsgrhsrtgh',
'date' => '2014-06-13',
'image' => '/uploads/stories/112.jpg',
'created' => '2014-06-13 07:43:18',
'modified' => '2014-06-13 07:43:18',
'created_by' => '1',
'original' => null,
'tags' => ''
),
'StoryChapter' => array(),
'StoryUser' => array(),
'StoryGroup' => array(),
'Favorite' => array(),
'Tag' => array()
)
)
I want the find function to order only the StoryChapter by created desc without affecting the order of the found stories .
I hope you understand what I mean .
Thank you
I solved the problem by adding the order in the hasMany array in the Story model
public $hasMany = array(
'StoryChapter' => array(
'className' => 'StoryChapter',
'foreignKey' => 'story_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => 'created ASC',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),

cakephp: structure database data returns

a possible return of a DB query looks like this:
array(
(int) 0 => array(
'Question' => array(
'id' => '737',
'question' => 'what is 1x7?',
),
'Answer' => array(
(int) 0 => array(
'id' => '2373',
'question_id' => '737',
'correct' => true,
'answer' => 'possible answer1',
'created' => '2014-05-08 13:46:43',
'modified' => '2014-05-08 13:46:43'
),
(int) 1 => array(
'id' => '2374',
'question_id' => '737',
'correct' => false,
'answer' => 'possible answer2',
'created' => '2014-05-08 13:46:43',
'modified' => '2014-05-08 13:46:43'
)
),
'Linkquestioncategory' => array(
(int) 0 => array(
'id' => '608',
'question_id' => '737',
'category_id' => '5',
'created' => '2014-05-08 13:46:47',
'modified' => '2014-05-08 13:46:47',
'Category' => array(
'id' => '5',
'name' => 'Simple Math',
'active' => true,
'linkquestioncategory_count' => '64',
'created' => '2014-02-03 09:20:54',
'modified' => '2014-03-04 14:47:05'
)
)
)
),
In order to clean it up to avoid sending to much unwanted data => my questions is => how can I get rid of those fields like
Answer.created
Linkquestioncategory.created
Linkquestioncategory.Category.created
I know that I can use conditions 'fields' to select the selected fields, but as far as I know, this works only for 'Question', but how can I manipulate those deeper array data?
Can I do this also with the 'fields' condition? If yes, how?
Thanks!!
http://nuts-and-bolts-of-cakephp.com/2008/09/05/example-of-cakephps-containable-for-deep-model-bindings/
This helped me a lot!!
Thanks!!

Using Containable behavior to filter results in Cakephp 2.2.4

I'm using containable behavior and the result of my find('all') is:
array(
(int) 0 => array(
'User' => array(
'id' => '106',
'email' => 'daje#daje.it',
'pwd' => '0433c024cb08be13000d59a347e640482843f46f177e95749dc6599c259617fd3491dcb940b47693cbbc7f65a2cc5ef62deca2e600c1be133ad54170f7d1fbd1',
'role_id' => '3',
'active' => '1'
),
'Lead' => array(
'id' => '6'
),
'Estimate' => array(
(int) 0 => array(
'lead_id' => '6',
'Estimate' => array(
(int) 0 => array(
'TOT_count' => '2'
)
)
)
)
)
)
I need to to count how many estimates there are in the lead.
The total (2) is correct, but i see nested 'Estimated' array, why ?
The result i would like to get is:
array(
(int) 0 => array(
'User' => array(
'id' => '106',
'email' => 'daje#daje.it',
'pwd' => '0433c024cb08be13000d59a347e640482843f46f177e95749dc6599c259617fd3491dcb940b47693cbbc7f65a2cc5ef62deca2e600c1be133ad54170f7d1fbd1',
'role_id' => '3',
'active' => '1'
),
'Lead' => array(
'id' => '6'
),
'Estimate' => array(
'TOT_count' => '2'
)
)
)
This is the find:
$options = array(
'contain' => array(
'User',
'Estimate' => array(
'fields' => 'COUNT(*) AS TOT_count'
)
),
'conditions' => array('Lead.id' => 6),
'fields' => 'User.*',
'limit' => 1
);
debug($this->Lead->find('all', $options));
How can i do it?
Thanks!
When you use a "custom" AS statement, in your case TOT_count, Cake will always put this in a result key called 0. You can avoid this by defining TOT_count as a virtualField in your model. That way it will be nested directly under the model name in your resultset.
Secondly, the lead_id is forcedly retrieved, because it is "needed" to make the join with the Lead model. It can not properly retrieve all the data without that piece of information there.

Categories