// in Person
public $hasMany = array(
'PersonRecommendation' => array(
'className' => 'PersonRecommendation',
'foreignKey' => false,
'dependent' => true,
),
)
// in PersonRecommendation
public $belongsTo = array(
'Person' => array(
'className' => 'Person',
'foreignKey' => false,
'conditions' => array('Person.email = PersonRecommendation.email'),
),
);
When I query these out with find() the Person returns ALL recommendations. Not just those associated by email. I've tried a variety of different things, and I'm stumped. Can someone help?
Using cake 2.4.5.
You need to change the Person model
public $hasMany = array(
'PersonRecommendation' => array(
'className' => 'PersonRecommendation',
'foreignKey' => false,
'dependent' => true,
'conditions' => array('Person.email = PersonRecommendation.email')
)
)
Try the following:
'conditions' => array($Person->email => $PersonRecommendation->email)
Related
My Cakephp Application Has the following models with relations ships
class Category extends AppModel {
public $hasAndBelongsToMany = array(
'Product' => array(
'className' => 'Product',
'joinTable' => 'products_categories',
'foreignKey' => 'category_id',
'associationForeignKey' => 'product_id',
'unique' => 'keepExisting',
),
);
}
class Product extends AppModel {
public $primaryKey = 'id';
public $hasMany = array(
'ProductSwatch' => array(
'className' => 'ProductSwatch',
'foreignKey' => 'product_id',
'dependent' => true
),
'ProductDimension' => array(
'className' => 'ProductDimension',
'foreignKey' => 'product_id',
'dependent' => true
),
'ProductCare' => array(
'className' => 'ProductCare',
'foreignKey' => 'product_id',
'dependent' => true
),
'ProductDimension' => array(
'className' => 'ProductDimension',
'foreignKey' => 'product_id',
'dependent' => false,
),
'ProductCare' => array(
'className' => 'ProductCare',
'foreignKey' => 'product_id',
'dependent' => false,
),
'Review' => array(
'className' => 'Review',
'foreignKey' => 'product_id',
'dependent' => true,
)
);
}
When i am finding all the Category elements only Product Model contents are coming is there any way to get the Products associations(ProductDimension, ProductSwatches, etc) when we fetch the Categories model?
By default CakePHP 2 recursion level is 1st level association only.
You can use recursive option of find (or model property) to fetch deep associations.
For more information about model recursive property, see: http://book.cakephp.org/2.0/en/models/model-attributes.html#recursive
For example:
$this->Category->find('all', array(
'recursive' => 2,
'conditions' => array(), // Your conditions, etc.
));
Another (and better way) is using Containable behaviour.
add
public $actsAs = array('Containable');
to your model(s) to enable Containable behaviour. Then you can use:
$this->Category->find('all', array(
'contain' => array(
'Product' => array(
'ProductSwatch',
'ProductDimension',
'ProductCare',
'Review',
),
),
'conditions' => array(), // Your conditions, etc.
));
to fetch deeper associations.
For more information about Containable behaviour and deeper associations, see http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html#containing-deeper-associations
I have the following code that gives an error from the moment I do a find condition on the associated Model (HABTM):
class Users extends Model{
public $useTable = 'users';
public $hasAndBelongsToMany = array(
'UserCategories' => array(
'className' => 'UserCategories',
'joinTable' => 'user_categories_link',
'foreignKey' => 'user_id',
'associationForeignKey' => 'category_id',
'unique' => false,
)
);
public function getData($page = 0, $category = '', $subcategory = ''){
return $this->find('all', array(
'limit' => 6,
'page' => $page,
'conditions'=> array(
'active'=> 1,
'UserCategories.category_name' => $category, // THIS GIVES ERROR
'UserCategories.category_subcategory' => $subcategory, // THIS GIVES ERROR
)
));
}
In my Controller:
$this->Users->getData(0, 'somemaincategory', 'somesubcategory');
I can't seem to do conditions on the related HABTM-Model (UserCategories in this case). I also tried to use 'contain' (with $actsAs), but then he stills gives me all the User data even if there is no Category linked with it. The Category array is in that case just blank.
Hope someone can help me.
Thanks in advance,
AƤron
Do a manual join. You can use this to do an actual inner join (contain will act as a left join). http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#joining-tables
$this->find('all',
array(
'conditions' => array(
'active' => 1,
),
'joins' => array(
array(
'table' => 'user_categories_link',
'alias' => 'UserCategoriesLink',
'type' => 'inner',
'conditions' => array(
'UserCategoriesLink.user_id = User.id'
),
),
array(
'table' => 'user_categories',
'alias' => 'UserCategories',
'type' => 'inner',
'conditions' => array(
'UserCategories.id = UserCategoriesLink.category_id',
'UserCategories.category_name' => $category,
'UserCategories.category_subcategory' => $subcategory,
),
)
),
)
);
I have 4 model:
Item------hasMany---->Detail
Item------hasMany---->Favourite
Item------hasMany---->Category
How can I find all Item that has Favourite.member_id = '8' and Category.item_category_id = '1'
Here is my Item model relation:
public $hasMany = array(
'Detail' => array(
'className' => 'Detail',
'foreignKey' => 'item_id',
'dependent' => true,
'conditions' => '',
'order' => 'created DESC',
),
'Category' => array(
'className' => 'Category',
'foreignKey' => 'item_id',
'dependent' => true,
'conditions' => '',
'order' => 'created DESC',
),
'Favorite' => array(
'className' => 'Favorite',
'foreignKey' => 'item_id',
'dependent' => true,
'conditions' => '',
'order' => 'created DESC',
)
);
I used this query() and it's ok:
$this->set('test',$this->Item->query("SELECT items.*
FROM items, categories, favourites
WHERE items.id = items_item_categories.item_id
AND items.id = favorites.item_id
AND categories.item_category_id = 1 AND favourites.member_id = 8"));
But I don't like using query(), and I change it into find(), and it seems not good:
$this->set('test',$this->Item->find('all', array(
'contain'=>array(
'ItemDetail',
'Category'=>array('conditions'=>array('Category.item_category_id'=>1)),
'Favorite'=>array('conditions'=>array('Favorite.member_id'=>8)));
You need call the containableBehaivor on your model
<?php
class Item extends AppModel {
public $actsAs = array('Containable');
}
in your controller you can make the query
$items = $this->Item->find('all', array(
'contain'=>array(
'ItemDetail',
'Category'=>array(
'conditions'=>array('Category.item_category_id'=>1)
),
'Favorite'=>array(
'conditions'=>array('Favorite.member_id'=>8)
)
)
);
$this->set('test', $items);
try using Joins
$items = $this->Item->find('all', array(
'joins' => array(
array(
'table' => 'categories',
'alias' => 'Category',
'type' => 'inner',
'conditions'=> array('Category.item_category_id' => 1)
),
array(
'table' => 'favorites',
'alias' => 'Favorite',
'type' => 'inner',
'conditions'=> array('Favorite.member_id' => 8, 'Item.id = Favorite.item_id')
)
),
'contain'=>array('ItemDetail','Category','Favorite')
);
$this->set('test', $items);
You could also try something like this:
$this->Item->hasMany['Favorite']['conditions']['member_id'] = 8;
Which has the same effect as rebinding the model with the condition.
Just a possible issue. The above will add the condition for the rest of the request, if you want to rollback to the previous behavior, you need to unset the condition:
unset($this->Item->hasMany['Favorite']['conditions']['member_id']);
Remember to set the $this->Item->recursive property to the desired value (recursive attribute). The default it's 1, which it's the minimum you need for this to work.
I use Cakephp framework, and I have problem with my association.
How create belong to association in models in cake php.
When I use belongto and hasMany in my model.
Can I find sample model to view this example?
Simple belongsTo association:
<?php
class Profile extends AppModel {
var $name = 'Profile';
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
);
}
?>
Simple hasMany association:
<?php
class User extends AppModel {
var $name = 'User';
var $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'user_id',
'conditions' => array('Comment.status' => '1'),
'order' => 'Comment.created DESC',
'limit' => '5',
'dependent'=> true
)
);
}
?>
More specific information about associations is in the CakePHP Book.
User has Many Photos
Photos belongs to User
In User Model :
var $hasMany = array(
'Photo' => array(
'className' => 'Photo',
'foreignKey' => 'user_id'
);
In Photo Model :
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'PhotoAlbum' => array(
'className' => 'PhotoAlbum',
'foreignKey' => 'photo_album_id',
'conditions' => '',
'fields' => '',
'order' => '',
))
I have the following relationships set up:
Teacher:
var $hasAndBelongsToMany = array(
'Classroom' => array(
'className' => 'Classroom',
'joinTable' => 'classrooms_teachers',
'foreignKey' => 'teacher_id',
'associationForeignKey' => 'classroom_id',
'unique' => true,
)
);
Classroom:
var $hasAndBelongsToMany = array(
'Teacher' => array(
'className' => 'Teacher',
'joinTable' => 'classrooms_teachers',
'foreignKey' => 'classroom_id',
'associationForeignKey' => 'teacher_id',
'unique' => true,
)
);
var $hasMany = array(
'Student' => array(
'className' => 'Student',
'foreignKey' => 'classroom_id',
'dependent' => false,
),
);
Student:
var $belongsTo = array(
'Classroom' => array(
'className' => 'Classroom',
'foreignKey' => 'classroom_id',
),
);
I am trying to create a dashboard for the teachers, where all students associated with the teacher through the classroom are displayed.
I am using the following find operation:
$students = $this->Teacher->Classroom->find('all', array(
'conditions' => array('Classroom.teacher_id' => $this->Access->getTeacherId()),
));
However, I am getting an error: Unknown column 'Classroom.teacher_id' in 'where clause'
I must be doing something wrong because cake is not doing the associations.
Any ideas?
This is the correct way of achieving this:
$this->Teacher->bindModel(array('hasOne' => array('ClassroomsTeachers')));
$students = $this->Teacher->find('all', array(
'conditions' => array('ClassroomsTeachers.teacher_id' => $this->Access->getTeacherId()),
'recursive' => 2
));
I hope it helps someone!
That's not the best way. Just use containable and find('first'), you don't need find all:
$students = $this->Teacher->find('first', array(
'conditions' => array('Teacher.id' => $this->Access->getTeacherId()),
'contain' => array('Classroom'=>array('Student'))
));
That will get you all the classrooms associated with the teacher, and all students in those classrooms.
I made a behavior to solve the HABTM problem.
Posted my answer here:
HABTM Find with CakePHP 2.0