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' => '',
))
Related
'books
id,name
categories
id,name
books_categories
id,book_id,category_id'
' App::uses('AppModel', 'Model');
class Book extends AppModel {
public $useTable = 'books';
public $belongsTo = array(
'Agerange' => array(
'className' => 'Agerange',
'foreignKey' => 'agerange_id'
),
'Publication' => array(
'className' => 'Publication',
'foreignKey' => 'publication_id'
),
);
public $hasMany = array(
'Category' => array(
'className' => 'Book_Category',
'foreignKey' => 'book_id',
'joinTable' => 'books_categories',
'fields' => array('Category_id',),
)
);
}
<?php
App::uses('AppModel', 'Model');
class Book_Category extends AppModel {
public $useTable = 'books_categories';
public $belongsTo = array(
'Book' => array(
'className' => 'Book',
'foreignKey' => 'book_id'
),
'Category' => array(
'className' => 'Category',
'foreignKey' => 'category_id'
)
);
}
in BooksController ......
$this->paginate = array(
'contains'=>array('Book','Publication','Agerange','Book_Category'),
'order' => 'Book.id ASC');
$books = $this->paginate('Book');
enter code here
{
Book: {id: "111", title: "ABC", subtitle: "English Today Primer", author: "Pruthviraj",…},…}
Agerange:{id: "31", from: "0", to: "2", status: true}
Book:{id: "111", title: "ABC", subtitle: "English Today Primer", author: "Pruthviraj",…}
Category:[{Category_id: "5", book_id: "111"}]
}'
Output Now I am getting only category_id:5 it's okay but I want name field also of category so How can I get name field of category using Book and Book_Category?
Modify your contain array by adding Categoy to Book_Category
$this->paginate = array(
'contains' => array(
'Book',
'Publication',
'Agerange',
'Book_Category' => 'Category'
),
'order' => 'Book.id ASC'
);
OR Use hasAndBelongsToMany association, it's much simpler
Start by deleting the Book_Category
Then change the book Model
class Book extends AppModel {
public $useTable = 'books';
public $belongsTo = array(
'Agerange' => array(
'className' => 'Agerange',
'foreignKey' => 'agerange_id'
),
'Publication' => array(
'className' => 'Publication',
'foreignKey' => 'publication_id'
),
);
public $hasAndBelongsToMany = array(
'Category' => array(
'className' => 'Category',
'joinTable' => 'books_categories',
'foreignKey' => 'book_id',
'associationForeignKey' => 'category_id'
)
);
}
Then, in your controller change the pagination setting like this
$this->paginate = array(
'contains' => array(
'Publication',
'Agerange',
'Category'
),
'order' => 'Book.id ASC'
);
#link Cakephp HABTM association
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
// 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)
Company class
public $hasMany = array(
'Person' => array(
'className' => 'Lasso.Person',
'foreignKey' => 'company_id',
)
Person class
public $belongsTo = array(
'Company' => array(
'className' => 'Lasso.Company',
'foreignKey' => 'id',
'conditions' => '',
'fields' => 'company',
'order' => ''
)
);
How do I get my company_id field within my People views to be the display name of Company rather than just the value of company_id?
public $displayField = 'companyName';
In your Person class you can write that:
public $belongTo = array(
'Company' => array(
'className' => 'Lesso.Company',
'foreignKey' => 'company_id', // Here use company_id instead of id
.....
)
);
and also you need to put company_id field in persons table.
I know that i can easily find related model-data through model associations, if I select a single entry. But what I want to do is to get the first image as a thumb for the galery, when I use find('all') for the index-page.
My relations (Galleries are named Albums) are:
//Album-Model
public $hasMany = array(
'Picture' => array(
'className' => 'Picture',
'foreignKey' => 'album_id',
'dependent' => true,
'conditions' => ''
)
);
and:
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Album' => array(
'className' => 'Album',
'foreignKey' => 'album_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
EDIT :
This should worked I tested it on my own!
Before your query add the following lane to specify the recursivity.
$this->Albums->recursive = 1;
$this->set('Albums', $this->Album->find('all'));
This way, it will also send the Pictures data. Then in your model associations, you can specify to only return the first image with the Album if that's what you want!
Just add 'limit' => '1', in your hasMany => Comments array, in Album Model.
Then you can iterate in your view doing
foreach($Albums as $Album){
$Album['Album']; // ALBUMS info do whatever
$Album['Picture']; // The thumbnail
}
EDIT2: I've just see you can also do
$this->Album->find('all', array('recursive' => 1));