how to make associations between grand parent & parent & child in cakephp 2 - cakephp

I have 4 tabels
stores
categories
items
item_images
Now i want to make association between them categories have store_id foreign key and items table have category_id and item_images have item_id foreign key.
public $hasMany = array(
'Item' => array(
'className' => 'Item',
'foreignKey' => 'category_id'
));
The above association is for category that find the related items but i want to do associate it with item_images. How i can do it with item_images now?
In Controller i have this query
$storeCategoriesDetails = $this->Category->find("all", array('conditions' => array('Category.storeId' => $id)));

You want to put your association for the item_images on the Item model like you've done for items on the Category model. You can then retrieve the item images along with the items when retrieving categories using contain:-
$storeCategoriesDetails = $this->Category->find('all', array(
'contain' => array('Item' => array('ItemImage'))
'conditions' => array('Category.storeId' => $id)
));

I added this line in my controller function and it's working now.
$this->Category->Behaviors->load('Containable');

Related

Saving data with HABTM and HasMany looses foreignKey

I have a User model with two relations:
HasAndBelongsToMany
public $hasAndBelongsToMany = array(
'group' => array(
'className' => 'group',
'foreignKey' => 'user_id'
)
);
HasMany
public $hasMany = array(
'phonenumber' => array(
'className' => 'phonenumber',
'foreignKey' => 'user_id'
)
);
Phonenumber and Group have set
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
);
When I use
$this->saveAll(array(
'User' => $data,
'phonenumber' => $numbers, //array with data
'group' => $groups //array with data
)
);
The data gets saved in the tabels but User_id is "0" in phonenumber and group table.
How can I get the correct ID saved ? (CakePHP v 2.5)
FWIW saveAll() should work as advertised, populating the new user_id in the child tables in one fell swoop.
Have you paid attention to the relevant options: atomic & deep?
Especially if database does not support transactions, you'll need to pass in atomic:
$this->saveAll(array(
'User' => $data,
'phonenumber' => $numbers, //array with data
'group' => $groups //array with data
),
array('atomic' => false)
);
Considering the CakePHP documentation you will find this hint:
When working with associated models, it is important to realize that
saving model data should always be done by the corresponding CakePHP
model. If you are saving a new Post and its associated Comments, then
you would use both Post and Comment models during the save operation
(http://book.cakephp.org/2.0/en/models/saving-your-data.html#saving-related-model-data-hasone-hasmany-belongsto)
Based on that information I suggest you try the following:
$this->User->save($data); // first save the user
Assuming you have multiple numbers:
foreach($numbers as $key => $nbr) {
// set user_id related data
$numbers[ $key ]['Phonenumber']['user_id'] = $this->User->id;
}
Finally save your related data:
$this->User->Phonenumber->saveAll($numbers);
Since this code is untested you may need to take some adjustments. Always ensure to follow the Cake-Conventions and use CamelCase ModelNames.

CakePHP, don't know how to select category name from table product and category

I am very new in cakephp
I have two table tb_product and tb_category
I want to select like sql below. How can I do it with cakephp?
SQL:
SELECT tb_product.id, tb_product.name, tb_category.name
FROM tb_product
INNER JOIN tb_category
WHERE tb_product.cat_id = tb_category.cat_id"
Thank you all helper!
tb_product:
----------
id
name
===========
tb_category:
-----------
cat_id
name
==========
Thank you in advanced !!!
You can either create a model association in your Cake model for Product to automatically join to Category in a hasOne relationship based on the cat_id foreign key, or you can do it with your find() query as a manual join:
$results = $this->Product->find('all', array(
'joins' => array(
array(
'table' => 'tb_category',
'alias' => 'Category',
'type' => 'INNER',
'conditions' => 'Category.cat_id = Product.cat_id'
)
),
'fields' => array(
'Product.id',
'Product.name',
'Category.name'
)
));
A model association would look something like this:
class Product extends AppModel {
// ...
public $hasOne = array(
'Category' => array('foreignKey' => 'cat_id')
);
}
Then when you query your product model, categories that match should be returned with it:
$results = $this->Product->find('all');

pagination; Results from multiple models

I have built a cake model that, when searched, needs to return paginated results that exclude some items based on data in another model.
I have a model called Box and a model called Item.
Each box can have 0 or more items, but I only want the boxes with 1 or more items with the category of Fruit to appear in a pagination result.
The Box model has a 'hasMany' association with the Item model.
The Item model has a field called 'is_friut'.
take care,
lee
This will make an inner join between the tables, only when the item is_fruit.
public $paginate = array(
'joins' => array(
array(
'table' => 'items',
'alias' => 'ItemJoin',
'type' => 'INNER',
'conditions' => array(
'ItemJoin.is_fruit' => 1
)
)
)
);

CakePHP 2.1 - Saving (and creating) multiple Join Models and associated models

My model relationship is as follows:
Student hasMany ClassStudent
Class hasMany ClassStudent
ClassStudent belongsTo Student
ClassStudent belongsTo Class
ClassStudent is a join model.
What I want to do is create Student(s), use an existing Class or create a new one, and create a join model record that links the Students and classes.
I want to do this all in one call to save (if this is even possible).
I have tried:
$data = array(
'Student' => array(
'0' => array( ... ), // Data in here
'1' => array( ... ),
...,
'n' => array( ... )
),
'Class' => array(
'class_id' => x // The class that I want the above students to be associated with
)
)
What I want to do is create n records of students and also add them to a class (possibly creating a class at the same time if the users wants to add a new one). I also want to create a join model record for each Student to the Class when I am creating the Student records.
Is this possible? I am using Cake 2.1.0 (today's stable release), and I have tried the different types of saveAll (saveAssociated and saveMany) with $options['deep'] = true.
Is it possible my data array is not in the correct format?
EDIT:
I have also tried:
$data = array(
'ClassStudent' => array(
'0' => array(
'Student' => array (...), // Data
'Class' => array(id => x) // The id of the Class the Student should be associated to
...,
'n' => array(
'Student' => array(...), // n-th Student
'Class' => array(id => x)
)
);
$this->saveAll($data['ClassStudent'], array('deep' => true));
In the above case, it successfully creates new Student records in the students table, but nothing is created in the join table.
saveAll (saveAll is a wrapper to saveMany and saveAssociated) is the right tool for the job. Take a look at the documentation for saveAll, I don't see any notes about it changing for 2.1. Having taking more time to read, here are some thoughts
First off, is there a type in your array structure. You have
'Class' => array ( 'class_id' => x )
If the Class is already defined and you are just wanting to add a student, then it would be
'ClassStudent' => array( 'class_id' => x )
With that said, CakesPHP ORM should allow you to use a saveAll with on a hasMany using a numerical index, so if assuming you have a typo, there follow might work for you
$data = array(
'Student' => array(
'0' => array( ... ), // Data in here
'1' => array( ... ),
...,
'n' => array( ... )
),
'ClassStudent' => array(
'class_id' => x // The class that I want the above students to be associated with
)
)
$this->ClassStudent->saveAll($data);

CakePHP Model Relationship with Multiple Foreign Keys

In my CakePHP app I have models for Matches and Teams. Each Match has a home_team_id and an away_team_id, both of which reference a different Team.
In my team.php file, I am able to form the relationship for a Team's home matches:
var $hasMany = array(
'HomeMatch' => array('className' => 'Match', 'foreignKey' => 'home_team_id'),
'AwayMatch' => array('className' => 'Match', 'foreignKey' => 'away_team_id')
);
My problem is that I cannot automatically retrieve a Team's home and away Matches in a single array. That is, the retrieved Matches are returned in separate HomeMatch and AwayMatch arrays, which causes sorting difficulties.
I have tried the following:
var $hasMany = array(
'Match' => array('foreignKey' => array('home_team_id', 'away_team_id'))
);
...with no luck.
Any ideas on how to combine these two foreign keys into a single relationship?
Thanks, Ben
A custom finderQuery should do the trick:
public $hasMany = array(
'Match' => array(
'className' => 'Match',
'foreignKey' => false,
'finderQuery' => 'SELECT *
FROM `matches` as `Match`
WHERE `Match`.`home_team_id` = {$__cakeID__$}
OR `Match`.`away_team_id` = {$__cakeID__$}'
)
);
I was having a similar issue and instead of creating a finderQuery I used the conditions operator and it worked great!
public $hasMany = array(
'Match' => array(
'className' => 'Match',
'foreignKey' => false,
'conditions' => array(
'OR' => array(
array('Match.home_team_id' => '{$__cakeID__$}'),
array('Match.away_team_id' => '{$__cakeID__$}')
)
),
)
);
They are returned in seperate array's because the sort of represent different models (in this particular case the model is the same).
You should probably build a helper method to go over the retrieved data (in the model object or in a separate helper class) and "flatten" it. then you'd be able to sort it.
Ken.

Resources