I have a Goal model that HasAndBelongsToMany Users. This HABTM is named Participant. When I try to find all the Participants of a goal, the join table for this HABTM is not being used. Here is the related code in the goal model.
class Goal extends AppModel {
var $hasAndBelongsToMany = array(
'Participant' => array(
'className' => 'User',
'joinTable' => 'goal_participants',
'foreignKey' => 'goal_id',
'associationForeignKey' => 'user_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
));
function getParticipantIDs($goalID) {
$this->bindModel(array('hasOne' => array('Participant')));
return $this->find('list', array(
'fields' => array('Participant.user_id'),
'conditions' => array('Participant.goal_id' => $goalID)
));
}
}
I am binding the Participant as hasOne so that it will create a join in the query, but I get the following error:
Warning (512): SQL Error: 1054: Unknown column 'Participant.user_id' in 'field list' [CORE\cake\libs\model\datasources\dbo_source.php, line 525]
Query: SELECT `Participant`.`id`, `Participant`.`user_id` FROM `users` AS `Participant` WHERE `Participant`.`goal_id` = '19' AND `Participant`.`status` != 2
I edited the answer after OP's comment.
If i understand well what you intend to do, this piece of code might help :
function getParticipantIDs($goalID) {
$participants = $this->GoalParticipant->find('list', array(
'fields' => array('user_id'),
'conditions' => array('goal_id' => $goalID)
));
return array_values($participants);
}
I'm not 100% sure GoalParticipant is the correct syntax. I'm pretty sure that if the join table was named goals_participants, the correct syntax would be GoalsParticipant but as it's named goal_participants I guess it might be GoalParticipant.
Related
I need to get data(all the id of the assurance that related to that Indicator datum) from assurances_indicator_data,and I didn't know the right way to join data in CakePHP my code didn't work and it return an empty array.
IndicatorDatum Model :
public $hasAndBelongsToMany = array(
'Assurance' => array(
'className' => 'Assurance',
'joinTable' => 'assurances_indicator_data',
'foreignKey' => 'indicator_datum_id',
'associationForeignKey' => 'assurance_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
function getIndicatorDataAssurance($indi_id){
$assuranceData = $this->find('all',array(
'joins' => array(
array('table' => 'assurances_indicator_data',
'type' => 'INNER',
'conditions' => array(
'AssurancesIndicatorData.indicator_datum_id' => $cun_indi)))));
return $assuranceData;
}
}
The easiest way to join tables in CakePhp is to have to models each representing a table in your database.
An example below, you can modify it to the names of your tables and models:
class ModelOne extends AppModel{
public $belongTo = array('ModelTwo');
}
class ModelTwo extends AppModel{
public $hasMany = array('ModelOne');
}
Then in your controller if you query any of these models, your response array should contain data from both tables.
I have a self reference table defined thus:-
public $hasMany = array(
'ChildCategory' => array(
'className' => 'Category',
'foreignKey' => 'parent_category_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
public $belongsTo = array(
'ParentCategory' => array(
'className' => 'Category',
'foreignKey' => 'parent_category_id',
'conditions' => array('ParentCategory.parent_category_id' => '0'),
'fields' => '',
'order' => ''
)
);
We only have one level of parent child so a tree is alittle ott. I'm trying to code the find to get a list of parents only for the add edit functions.
$parentCategories = $this->Category->ParentCategory->find('list');
However the sql does not contain my condition???
SELECT ParentCategory.id, ParentCategory.name FROM bidup.categories AS ParentCategory WHERE 1 = 1
Is there a reason that the condition is not being included?
The conditions on the $belongsTo relationship will only apply when retrieving the ParentCategory from a query on Category (assuming the relationships you show are just in the Category model).
This means if you did a find() on Category and included ParentCategory through either the recursive or contain parameters, or maybe used read() then that condition would be used.
When you query directly on ParentCategory that condition in the model is by-passed, you're just using that relationship as a short-cut to getting to that model without having to load it directly or put it in your $uses.
As user2076809 suggested, if you specifically want to use list on ParentCategory then your best option is likely to include the condition yourself:
$parentCategories = $this->Category->ParentCategory->find(
'list',
array(
'conditions' => array('ParentCategory.parent_category_id' => 0),
)
);
I have the problem in Cakephp that when I define
public $hasAndBelongsToMany = array(
'User' => array(
'className' => 'User',
'joinTable' => 'groups_users',
'foreignKey' => 'group_id',
'associationForeignKey' => 'user_id',
'unique' => 'keepExisting',
'conditions' => 'User.active=1',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
with the conditions field set, so that only users that are active are fetched from the DB, that I get the error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'User.active' in 'where clause'
for the SQL Query:
SELECT `GroupsUser`.`user_id` FROM `groups_users` AS `GroupsUser` WHERE `GroupsUser`.`group_id` = 123 AND `User`.`active`=1
Because obviously it only fetches the results from the join table. So I found here: http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasandbelongstomany-habtm in the description for conditions.
conditions: an array of find() compatible conditions or SQL string. If
you have conditions on an associated table, you should use a ‘with’
model, and define the necessary belongsTo associations on it.
What is a 'with' model and how would I implement it?
Thanks a lot in advance!
Although this question is quite old I've recently encountered the same problem and wanted to document my solution. In the above example instead of referencing the User I've had to do a simple sub query to get the associated field like this:
public $hasAndBelongsToMany = array(
'User' => array(
'className' => 'User',
'joinTable' => 'groups_users',
'foreignKey' => 'group_id',
'associationForeignKey' => 'user_id',
'unique' => 'keepExisting',
//'conditions' => 'User.active=1',
'conditions' => array('(SELECT active FROM users WHERE users.id = GroupsUser.user_id)'=>1),
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
In my similar example finds & saves now work.
I am trying to retrieve data from a simple table and populate a select field form.
There are two tables, Acronyms and Topics.
Currently I have:
In my acronyms_controller (method add()):
$topics = $this->Acronym->Topic->find('list');
$this->set(compact('topics'));
In my acronym (model):
var $belongsTo = array(
'Topic' => array(
'className' => 'Topic',
'foreignKey' => 'topic_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
In my Topic model:
var $hasMany = array(
'Acronym' => array(
'className' => 'Acronym',
'foreignKey' => 'topic_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
in my Acronym add view:
<?php echo $this->Form->input('topic_id'); ?>
I do not know why this is not working (it is not retrieving the Topic data in the select field). I download a simple application and did the same exercise and it did very well. I do not know what I am missing.
I would appreciate if I have your help.
Your code all appears to be correct. If the topic name is not appearing in the select field, then it is probably because the field in the database table is not correct.
For Cake to automagically popular the select with a list of Topic names, there must be a field in your Topictable called name.
Otherwise, there must be something else in your controller conflicting with this, but I'd need to see the entire add() method to determine this.
I am trying to query a hasAndBelongsToMany relationship in Cakephp 1.3, but it looks like the SQL query being run is not doing a Join on the many to many table.
I have a users table, projects table, and users_projects table. I want to get a list of all projects a user is associated with in a separate Allocations controller.
I have been reading the cakephp book on the topic: http://book.cakephp.org/view/1044/hasAndBelongsToMany-HABTM
So I have been trying this:
var_dump($this->Allocation->User->Project->find('list',array('conditions'=>array('Project.user_id'=>'21'))));
However that does not work, It returns nothing and this error:
Warning (512): SQL Error: 1054: Unknown column 'Projects.user_id' in 'where clause' [CORE/cake/libs/model/datasources/dbo_source.php, line 681]
Query: SELECT `Project`.`id`, `Project`.`name` FROM `projects` AS `Project` WHERE `Projects`.`user_id` = '21'
It looks like cakephp is not doing the required join.
This is in my projects model:
var $hasAndBelongsToMany = array(
'User' => array(
'className' => 'User',
'joinTable' => 'users_projects',
'foreignKey' => 'project_id',
'associationForeignKey' => 'user_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
And this is in my users model:
var $hasAndBelongsToMany = array(
'Project' => array(
'className' => 'Project',
'joinTable' => 'users_projects',
'foreignKey' => 'user_id',
'associationForeignKey' => 'project_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
So, what is the correct syntax to get the list of projects for a given user on a many to many relationship in cakephp?
Perhaps that's because you didn't make the two table names connected in alphabetical order.users_projects should be projects_users.
You are getting this error because you are using the find type 'list'. Cake's default behaviour is to select the ID and NAME fields when using this find type.
Change your find type to 'all' to retrieve the results you are expecting:
var_dump($this->Allocation->User->Project->find('list',array('conditions'=>array('Project.user_id'=>'21'))));