HABTM delete constraint - cakephp

I've got two models Category and Item. Category can have many items and item can be in many categories so relation between them is HABTM.
My problem is that a category can be deleted even if items are in it.
I have a foreign key in the database table categories_items that RESTRICTS deletion, but it doesn't help.
What should I do to prevent category from being deleted if items are in it?

You need to overwrite the actual "delete" method in your CategoriesController to verify that there are no Items in the category before it is deleted.
Something like...
$c = $this->Category->findById($id);
$rels = $this->CategoriesItem->find('count', array('conditions' => array('CategoriesItem.category_id' => $id)));
if(count($rels) > 0) $this->Session->setFlash("NO WAY JOSE");
else $this->Category->delete($id);

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

How can I find a result by its row number?

Say I have two models, Foo belongsTo Bar:
$this->Foo->find('first',array(
'conditions'=>array(
'barRowNumber'=>$barRowNumber,
'fooRowNumber'=>$fooRowNumber)));
I can't just do the auto_increment id because they skip around when I add and delete records. So how can I use row number as a parameter for a find query in CakePHP?
If you dont have id then you should count the row where your search occur.
If you have ID then $this->Foo->id = $value is the key
If you have other search value then $this->Foo->findbyYourValue will do

How do I add multiple related records programmatically in a HABTM CakePHP relationship scenario?

I've got my models set up so that Users belong to Groups. There is a working HABTM relationship between these two.
The code below is used to populate the database with some demo data. Prior to the following snippet, the Groups table has been filled with some sample group data.
The code snippet below works. It adds records to the Users table and the join table (groups_users) gets the correct entries, too. So basically, the HABTM relationship works fine.
Here is my question: How do I add associations with multiple groups instead of just the single relationship? Doing a 'Group'=>array($group1, $group2) instead of the 'Group'=>$group1' as outlined below does NOT work. When I use an array, nothing at all is added to the join table.
Your help is greatly appreciated!
$groups = $this->Group->find('all');
for ($i=0; $i<=200; $i++) {
$groupIndex1 = rand(0, count($groups)-1);
$groupIndex2 = rand(0, count($groups)-1);
$this->User->set(
array(
'id'=>null,
'name'=>'Dummy User '.$i0,
'Group'=>$groups[$groupIndex1]
)
);
$this->User->save();
To save multiple groups for a single user, you will have to define hasMany relationship in your User model. And in your saving code it will looks like:
$groups = $this->Group->find('all');
for ($i=0; $i<=200; $i++) {
$groupIndex1 = rand(0, count($groups)-1);
$groupIndex2 = rand(0, count($groups)-1);
$data =
array('User' => array(
'id'=>null,
'name'=>'Dummy User '.$i0,
),
'Group'=> array($groups[$groupIndex1], $groups[$groupIndex2])
)
);
$this->User->saveAssociated($data, array('deep' => true);
This link might help you to understand 'deep' => true option.

CakePHP HABTM relationship, setting related records always adds new entry in jointable even if already exists

This is my code:
$charities = explode(',',$this->data['Charity']['charities']);
foreach ($charities as $key=>$charity){
$data['Charity'][$key] = $charity;
}
$this->Grouping->id = $this->data['Charity']['grouping_id'];
if ($this->Grouping->save($data)){
//Great!
}else{
//Oh dear
}
The code is from an action that gets called by AJAX. $this->data['Charity']['charities'] is a comma separated list of ids for the Charity model, which HABTM Grouping.
The code works fine, except that Cake doesn't seem to check whether that charity is already associated with that grouping, so I end up with lots of duplicate entries in the join table. I can see that this will be a pain later on so I'd like to get it right now.
What am I doing wrong?
Thanks
A few things I spotted:
A. Is $this->data['Charity']['charities'] an array with named keys corresponding to the table columns? Because inside the foreach() loop, you are taking the key and putting it in the $data['Charity'] array. The result could be a wrong format. The $data array for Model saves is commonly formatted as $data['Charity']['NAME_OF_COLUMN1], $data['Charity']['NAME_OF_COLUM2], and so on for each column that wants to be saved. So, if the keys are numbers, then you could be having something like: $data['Charity'][0], $data['Charity'][1], which is wrong.
B. HABTM Associations are saved differently. What I do recommend, is that you take a look at the book's section on saving HABTM. I save a HABTM relation like this (supposing a relation between users and coupons):
$this->data['Coupon'] = array('id' => 1, 'code' = 'BlaBla');
$this->data['User'] = array('id' => 33);
$this->Coupon->save($this->data, false);
So, as you can see, the $data array has a subarray named after the foreign model ('User') with the columns+values that I want to save. Then I save this array to the Coupon model.
C. Be aware that CakePHP will always delete old records and insert new ones within the join table when it is 'updating' HABTM relations. To avoid this, you set the 'unique' field to false in the Model's $HABTM configuration.

Resources