I have below defined in my model:
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'GroupBuy' => array(
'className' => 'GroupBuy',
'foreignKey' => 'group_buy_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
This however does not pull details from GroupBuy nor User table but it fetches only user_id and group_buy_id which are defined in this GroupBuyUser model.
I've set recursive two with below:
$this->GroupBuyUser->recursive = 2;
Is there something wrong I'm doing here?
Try the following code in your GroupBuyUser Model:
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
),
'GroupBuy' => array(
'className' => 'GroupBuy',
'foreignKey' => 'group_buy_id'
)
);
You don't need to set the recursive property to 2. This is basically used while we want to fetch result from deeper associated models.
Related
I am new in cakephp and trying my best to implement queries in cakephp.
I have this query
SELECT * FROM question join question_topic on question.question_id=question_topic.question_id join topic on topic.topic_id=question_topic.topic_id join user_topic on user_topic.topic_id=topic.topic_id where user_topic .user_id=10
I need this in cakephp.
What I have tried is this
$this->Behaviors->attach('Containable');
return $this->find('all', array(
'contain' => array(
'User',
'UserInfo.UserTopic'=>array(
'conditions'=>array('UserTopic.user_id'=>10)
),
'QuestionAndTopic.Topic','UpVoteQuestion','Answer','Answer.UserInfo'
),
'order' => 'rand()',
'recursive' => 0
));
But the query is not giving me a right results. Could you please take a look.
Question.php
class Question extends AppModel
{
public $useTable = 'question';
public $primaryKey = 'question_id';
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'fields' => array('User.user_id','User.email','User.active')
),
'UserInfo' => array(
'className' => 'UserInfo',
'foreignKey' => 'user_id',
)
);
public $hasMany = array(
'Answer' => array(
'className' => 'Answer',
'foreignKey' => 'question_id',
),
'QuestionAndTopic' => array(
'className' => 'QuestionAndTopic',
'foreignKey' => 'question_id',
)
);
public function latestQuestions(){
$this->Behaviors->attach('Containable');
return $this->find('all', array(
'contain' => array(
'User',
'UserInfo.UserTopic'=>array(
'conditions'=>array('UserTopic.user_id'=>10)
),
'QuestionAndTopic.Topic','UpVoteQuestion','Answer','Answer.UserInfo'
),
'order' => 'rand()',
'recursive' => 0
));
}
}
You can use Mysql query it will works as like as cakephp query
$this->Behaviors->query('SELECT * FROM question join question_topic on question.question_id=question_topic.question_id join topic on topic.topic_id=question_topic.topic_id join user_topic on user_topic.topic_id=topic.topic_id where user_topic .user_id=10');
Refer this link
$options['joins'] = array(
array('table' => 'books_tags',
'alias' => 'BooksTag',
'type' => 'inner',
'conditions' => array(
'Book.id = BooksTag.book_id'
)
),
array('table' => 'tags',
'alias' => 'Tag',
'type' => 'inner',
'conditions' => array(
'BooksTag.tag_id = Tag.id'
)
)
);
$options['conditions'] = array(
'Tag.tag' => 'Novel'
);
$books = $Book->find('all', $options);
make changes as per you table and fields.hope this helps.
I have 3 tables
students(id,name)
subjects(id, subject)
student_subjects(id,student_id,subject_id)
students table is related to subjects on many to many relation using student_subjects table
student model
public $hasMany = array(
'studentsSubject' => array(
'className' => 'studentsSubject',
'foreignKey' => 'students_id',
));
students_subjects model
public $belongsTo = array(
'Student' => array(
'className' => 'Student',
'foreignKey' => 'students_id',
));
when I query
$students = $this->Student->find('all');
debug($students);exit();
it returns like this
array(
'Student' => array(
'id' => '1',
'name' => 'smith',
),
'StudentSubject' => array(
0=>array(
'id' => '1',
'student_id'=>'1',
'subject_id'=>'1'
),
1=>array(
'id' => '2',
'student_id'=>'1',
'subject_id'=>'2'
),
)
)
while I want to have subject names instead of subjectID as below
I know I can make changes in find to have required result
but I mean, Is it possible like link students table with 'subjects' instead of 'student_subjects'
array(
'Student' => array(
'id' => '1',
'name' => 'smith',
),
'Subject' => array(
0=>array(
'id' => '1',
'subject'=>'maths',
),
1=>array(
'id' => '2',
'subject'=>'computer',
),
)
)
You made belongsTo with Student in students_subjects model. This is incorrect. Instead of that you need to make belongsTo with Subject.
For this, you should use a HABTM assosiation. With your three tables defined as you have, you need just two models and the HABTM relationship between them.
class Student extends AppModel {
public $hasAndBelongsToMany = array(
'Subject' =>
array(
'className' => 'Subject',
'joinTable' => 'student_subjects',
'foreignKey' => 'student_id',
'associationForeignKey' => 'subject_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'with' => ''
)
);
}
This way, you would have access as you want to the Subject model, through the Student model without any workaround.
Change model class name
Class Subject extends App_Model{
public $useTable = 'student_subjects';
}
I have tables below with HABTM associations.
user, group , groups_users
group , project, projects_groups
public $hasAndBelongsToMany = array(
'Group' =>
array(
'className' => 'Group',
'joinTable' => 'groups_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'group_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => ''
)
);
I am trying to get all users, as a list for checkboxes, that are on a project using project id using query below
$users = $this->User->Group->Project->find('list',
array(
'conditions' => array('Project.id' => $this->Session->read('Projectid'))
,'contain' => array(
'User' => array( 'fields' => 'User.id', 'User.email')
)
)
);
But error below
Model "Project" is not associated with model "User"
I have actually tried different ways to get this working but cant seem to get it right, how can i achieve what i want. cheers
I achieved what i wanted with joins , is there a way to do this by using model associations, instead of the manual joins option?
$options['joins'] = array(
array('table' => 'groups_users',
'alias' => 'gu',
'type' => 'LEFT',
'conditions' => array(
'gu.user_id = User.id',
)
),
array('table' => 'projectGroups',
'alias' => 'pg',
'type' => 'LEFT',
'conditions' => array(
'pg.group_id = gu.group_id',
)
)
);
$this->User->recursive = -1;
$options['conditions'] = array(
'pg.project_id = ' => $this->Session->read('Projectid'),
'User.Active = ' => true
);
$users = $this->User->find('list', $options);
I am trying to link a HABTM model with joins but I dont get any records from the joined tables.
I have data for the tutor id =2 and also I have this id of 2 in the other tables of tutors-subjects and also a key in the subject. i should not get NULL in the other tables. I dont get an error.
I want all the subjects for tutor id =2.
Here is the controller and model with the relationship
array(
(int) 0 => array(
'Subject' => array(
'id' => null,
'name' => null
),
'TutorsSubject' => array(
'id' => null,
'tutor_id' => null,
'subject_id' => null
),
'Tutor' => array(
'id' => '2',
'tutor_inactive' => false,
'first_name' => 'fred2',
'last_name' => 'blah',..........
class TutorsController extends AppController {
public function tutordetails() {
$options2['joins'] = array(
array('table' => 'tutors_subjects',
'alias' => 'TutorsSubject',
'type' => 'LEFT',
'conditions' => array(
'Tutor.id = TutorsSubject.tutor_id', //fixed 'Tutor.id = TutorsSubject.id', //
)
),
array('table' => 'subjects',
'alias' => 'Subject',
'type' => 'LEFT',
'conditions' => array(
'TutorsSubject.subject_id=Subject.id',
)
)
));
$options2['fields'] = array('Subject.*','TutorsSubject.*','Tutor.*');
$this->Tutor->recursive = -1;
$options2['conditions'] = array('Tutor.id' => 2);
$subject=$this->Tutor->find('all',$options2);
$this->set('subject', $subject);
debug($subject);
class Subject extends AppModel {
public $hasAndBelongsToMany = array(
'Tutor' => array(
'className' => 'Tutor',
'joinTable' => 'tutors_subjects',
'foreignKey' => 'subject_id',
'associationForeignKey' => 'tutor_id',
'unique' => 'keepExisting',
'conditions' => '',
)
);
}
class Tutor extends AppModel {
..
public $hasAndBelongsToMany = array(
'Subject' => array(
'className' => 'Subject',
'joinTable' => 'tutors_subjects',
'foreignKey' => 'tutor_id',
'associationForeignKey' => 'subject_id',
'unique' => 'keepExisting',
'conditions' => '',
),
);
UPDATE=AgRIZZO solved it and changed made above
Agrizzo had the answer Using JOINs when you have properly defined model relations is huge mistake. Use the framework for what it was defined for (and you need is well supported without the JOINs.). That being said - your problem is most likely this: '
Tutor.id = TutorsSubject.id' in your first JOIN definition. Try
'Tutor.id = TutorsSubject.tutor_id
I have 3 tables structure as...
SONG(id, status)
TRACKLIST(id, song_id, artist_id, status)
ARTIST(id, status)
I wish to have HABTM so I mentioned as..
Song MODEL
var $hasAndBelongsToMany = array(
'Artist' => array(
'className' => 'Artist',
'joinTable' => 'tracklists',
'foreignKey' => 'song_id',
'associationForeignKey' => 'artist_id',
'conditions' => array('tracklist.status' => '1')
'with' => 'Tracklist',
//'unique' => true
),
);
Artist Model
var $hasAndBelongsToMany = array(
'Song' => array(
'className' => 'Song',
'joinTable' => 'tracklists',
'foreignKey' => 'artist_id',
'associationForeignKey' => 'song_id',
'with' => 'Tracklist',
//'unique' => true
),
);
Tracklist Model
var $belongsTo = array(
'Song' => array(
'className' => 'Song',
'foreignKey' => 'song_id',
'dependent' => true
),
'Artist' => array(
'className' => 'Artist',
'foreignKey' => 'artist_id',
'dependent' => true
)
);
This way but issue is when I tried to find records from the Artist table it find all the records without any condition.
$artist_conditions = array('Artist.status' => '1');
$artist_list = $this->Song->Artist->find('list', array('conditions' => $artist_conditions ));
I wish to fetch only those artist related to the tracklist and having tracklist.status as 1. Is the relationship is correct?? Or I simply use hasMany with (Song, Artist) and BelongsTo with (Tracklist).
You can try this:
/* for example in songs controller */
public $uses = array('Song','Tracklist');
$artist_conditions = array('Artist.status' => '1');
$this->Tracklist->recursive = 1;
$artist_list = $this->Tracklist->find('list', array('conditions' => $artist_conditions ));