Select model object in cake php 3 - cakephp

I am new to cakePhp. I have two models name Category and SubCategory in CakePHP3. I want to select the object of Category model where id = 2 and related models of SubCategory. Please help me to get the data.

Use associations and containments, it's well explained in the manual.
http://book.cakephp.org/3.0/en/orm/associations.html
http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#retrieving-associated-data
Once you've setup the associations, you can simply query for the category and have the associated sub categories included automatically.
$query = TableRegistry::get('Categories')
->find()
->contain(['SubCategories'])
->where([
'id' => 2
]);
debug($query->toArray());

Related

Issue in hasMany associated model data update/modify

I have two table,
categories hasMany products
id
name
active
products belongsTo categories
id
name
category_id
active
When I am editing the categories, in the same time I am also displaying the Products related to the category so that I can update/modify products related to the category.
Issue:- When I add more products for the category that works fine but when I remove some products from the category,the removed product does not get deleted from the database. So I want to know that This functionality is supported by CakePHP or not. If yes please help me to find where I am going wrong.
Here is the save code:-
$categoryProducts = $this->Categories->get(1, [
'contain' => 'Products'
]);
if($this->request->is['post', 'put']){
$entity = $this->Categories->patchEntity($categoryProducts, $this->request->data);
$this->Categories->save($entity);
}
When you set up your hasMany relationship, add 'saveStrategy' => 'replace'. See the hasMany section of the manual for details.

Cakephp database associations

I have 3 tables in database:
Cakephp 3.
Cars{id, type_id,....}
Types{id, name,....}
Images{id, type_name,image_url,....}
And in model cars i would like to set relation to images, actually model associations.
I need to fetch image_url from images, with value type_id wich is the same in table Cars and in table Images. It means i can forget table Types.
Now i am fetching Images with join query from controller, but i would like to associate those models.
Query in controller looks like:
$query->join(['table' = 'Images',
'alias' => 'i',
'conditions' => 'Cars.type_id = i.type_id'
]);
This is relation type: 1 car can have 1 or more images, and 1 image can belong to 1 or many cars. It means M:M.
It should be relation belongsToMany.
I try to set diferent ralations option, from hasMany to belongsToMany it does not work.
Is it possible to do this at all, or it maybe isn't because one table does not contain primary key of another, and i am forced to use join query in controller?
Thany you for advice.
added contain with "recursion" in query:
$query->contain(['Cars','Types' => ['Images']]);
and i get what i needed.
best regards

CakePHP containable behaviour not firing

First time using Cake and its containable behaviour, but it's not working as expected ... or at all.
I'm trying to obtain a list of accessories for a product. Product model HABTM products (alias 'ProductRelation'). Join table is products_products which has two product ids - product_id and related_id. It's against this I want to pull the list of accessories (products driven from the related_id column) for a given product_id
In my Product model, I've added $actsAs = array('Containable');
And in my controller, a quick test of containable using reference from the cookbook fails to contain products at all, even without conditions.
debug($this->Product->find('all', array('contain' => 'ProductRelation')));
.. returns an array of every product in the db, with ALL related models - images, content tabs, ratings, reviews, pricing, etc I haven't tried applying any 'conditions' against this because the call as written should limit data to the product and it's ProductRelation data, according to the cookbook ...
Any tips?
It seems like you have recursive on. Try using the following:
debug($this->Product->find('all', array(
'contain' => 'ProductRelation',
'recursive' => -1
)));
If that works for you, you should start adding containable to the AppModel class and setting the recursive property to -1. This will ensure you only ever get the results you request.
NB: Cake does not join for HABTM, so you can not use ProductRelation in any conditions.

CakePHP Relationships over more then one Model/Table

I'm new to learning CakePHP. I did the Blog Tutorial and am now trying to add Categories for Posts. I created Category and SubCategory Models and MySQL DB Tables and I related the Models as follows:
Post -> "belongsTo" -> SubCategory -> "belongsTo" -> Category
Post -> Subcategory is working fine and I can resolve the SubCategory Name in the View via:
php echo $post['SubCategory']['name'];
Now: How do I go one step further in the relation and get the Category Name for a Post in the Post View (via the SubCategory)? The following obviously gives me the Category ID, but not it's name:
php echo $post['SubCategory']['category_id'];
Thanks a lot!
Check out the recursive parameter for a model and go for a step 2 (2 levels of depth). This would allow you to use the category if your definition is correct. Keep in mind that it would need to fetch a lot of data and this would affect the overall performance of the site.
You should look into ContainableBehavior, which will help you only grab the results you really need. The first thing I always suggest is changing $recursive = -1 and using Containable. This will also greatly improve the performance of your app because you will be performing less calls for data you don't actually use.
Using your example:
$results = $this->Post->find('all', array(
'contain' => array(
'SubCategory' => array(
'Category'
)
)
));
// in your view foreach loop
echo $post['SubCategory']['Category']['name'];

Cakephp habtm deep conditions

suppose you have those model relations:
Offer HABTM Category
How would you build the find conditions to find all the categories that have at least one offer. In the same time the Offer should be Offer.enabled => 1. So find all the categories with at least one enabled offer. The conditions to check in the offer model are several, but once I can check for the enabled, I think I will be able to check for any other field.
I could bind the habtm model to Category, but in this case I can't check the Offer.enabled condition. Maybe somehow using containable?
The sql query would be :
SELECT DISTINCT Category.nome from categories as Category
LEFT JOIN categories_offers AS CategoriesOffer
ON (CategoriesOffer.category_id = Category.id)
LEFT JOIN offers as Offer ON (CategoriesOffer.offer_id = Offer.id)
WHERE Offer.enabled = 1
Thank you
Use the conditions key in your relationship definition to set the relationship up only if Offer.enabled = 1. Taken from the book. eg:
class Category extends Model {
public $hasAndBelongsToMany = array(
'Offer' => array(
'conditions' => array( 'Offer.enabled' => 1 )
)
);
}

Resources