Delete multi level in cakephp ( chain delete ) - php

I want to delete all dependent rable record
My association
Branch Model
var $hasMany =array(
'Dealbranch' => array(
'className' => 'Dealbranch',
'foreignKey' => 'DLB_BR_ID',
'dependent' =>true
)
);
Dealbranch Model
var $belongsTo = array(
'Deal' => array(
'className' => 'Deal',
'foreignKey' => 'DL_ID',
'dependent' => true
),
'Branch' => array(
'className' => 'Branch',
'foreignKey' => 'DLB_BR_ID',
)
);
Deal Model
var $hasMany = array(
'Dealbranch' => array(
'className' => 'Dealbranch',
'foreignKey' => 'DLB_DL_ID',
)
);
In controller I have used
$this->Branch->delete($id,true);
Now here whem I am deleting branch , so dependent dealbranch deleted successfully but none of any deal record deleted
I want like : whem I am deleting branch , so all dependent dealbranch should be deleted and all dependent( depend on dealbranch) deal record should be deleted
here Deal is child of Dealbranch and Dealbranch is child of branch
Now, For one branch there are multiple record in Dealbranch, and for multiple Dealbranch there is one record in Deal
Please help me. I am using cakephp 2

All the model records that are associated with Branch can be deleted by using
$this->Branch->delete($id,true);
I think if you want to remove the deal records on deleting of branch records then your model Branch should be associated with Deal model.
Just try to add like this
Branch Model
var $hasMany =array(
'Dealbranch' => array(
'className' => 'Dealbranch',
'foreignKey' => 'DLB_BR_ID',
'dependent' =>true
),
'Deal' => array(
'className' => 'Deal',
'foreignKey' => 'your_foriegn_key',
'dependent' =>true
)
);
or you may try like this
Update:
According to your requirement here Deal is child of Dealbranch and Dealbranch is child of branch your model associations should be like this.
deal branch model should be like this.
DealBranch Model
var $belongsTo = array(
'Branch' => array(
'className' => 'Branch',
'foreignKey' => 'DLB_BR_ID',
)
);
var $hasMany = array(
'Deal' => array(
'className' => 'Deal',
'foreignKey' => 'DL_ID',
'dependent' => true
),
);
deal model should be like this.
Deal Model
var $belongsTo = array(
'Dealbranch' => array(
'className' => 'Dealbranch',
'foreignKey' => 'DLB_DL_ID',
)
);

While I know the people at cakephp do not use foreign keys in their databases and rely on the framework to take care of these details, in your case if the framework is giving you problems and you have control over the database update your foreign key constraints to CASCADE on DELETE DB operations.

The basic problem is in your data model. According to your model, any branch can be connected to zero or more deals and vice versa. Thus if you delete a branch, it does not make any sense to delete any deal, because the deal could be related to another branch. If the deal was deleted, the database integrity would be corrupted.
The setting you use is often used to model M:N relationship.1
The whole picture if your data model:
And what you really meant:
Branch model
var $hasMany =array(
'Deal' => array(
'className' => 'Deal',
'foreignKey' => <set_according_to_your_column_names>,
'dependent' =>true
)
);
Deal model
var $hasMany = array(
'Branch' => array(
'className' => 'Dealbranch',
'foreignKey' => <set_according_to_your_column_names>,
)
);
This way, you can in the controller call only:
$this->Branch->delete($id,true);
or even
$this->Branch->delete($id);
since the second parameter is true by default.
1 Example of M:N relationship is Person - Address. Anyone can use more than one address (e.g. home and work) and one address can be shared by more people (family, colleagues).

Related

Delete record from multiple tables when using a View CakePHP 2.8.x

I am using CakePHP 2.8.x and i'm looking for a way to delete records from 2 tables with 1 delete action.
I created a View from 3 tables: visitors, guests and registrations. These tables are connected through visitor_id.
In the Visitor Model i added the View in $useTable. Now when i press delete on, for example, visitor 1, i want to delete the records from visitor 1's guests and registrations tables and keep the visitor information in the visitor's table
I did found $this->Visitor->delete($id), but what parameters do i need to add to this function, so i can delete just the records from the guests and registrations tables?
If i need to give more information, i'm happy to help! Thx in advance
Update: The tables are associated. These are the models:
Visitor:
public $hasMany = array(
'Guest' => array(
'className' => 'Guest',
'foreignKey' => 'visitor_id',
'dependent' => false,
'exclusive' => false,
),
'Registration' => array(
'className' => Registration',
'foreignKey' => 'visitor_id',
'dependent' => false,
'exclusive' => false,
),
);
public $belongsTo = array(
);
Registration:
public $belongsTo = array(
'Visitor' => array(
'className' => 'Visitor',
'foreignKey' => 'visitor_id',
),
);
Guest:
public $belongsTo = array(
'Visitor' => array(
'className' => 'Visitor',
'foreignKey' => 'visitor_id',
),
there's the deleteAll() function in cake 2 (see the cookbook)
you have to pass to the function an array of conditions. In your case you want to delete all the Guests that have visitor_id = $id (the same for Registration).
$this->Visitor->Guest->deleteAll(array('visitor_id' => $id));
$this->Visitor->Registration->deleteAll(array('visitor_id' => $id));
this will delete all the Guests and the Registrations of the Visitor without touching the Visitor itself
you can try it,its worked for me
public function your_action($id=null){
$this->MainMdel->ConnectedModel1->deleteAll(array('ConnectedModel_id' => $id));
$this->MainMdel->ConnectedModel2->deleteAll(array('ConnectedModel_id' => $id));
}

Link the same model twice to another model in CakePhp

It's probably a very basic problem, but I can't wrap my head around it how to solve this properly.
In my application, I've got users who have multiple addresses with different purposes. For example, a user can have an Address and an InvoiceAddress. I want to store both addresses in the same table (the Address model) and then assign them to one User.
The respective models look something like:
Address:
public $belongsTo = array(
'Address' => array(
'className' => 'Address',
),
'InvoiceAddress' => array(
'className' => 'Address',
),
);
And the User:
public $hasOne = array(
'Address' => array(
'className' => 'Address',
),
'InvoiceAddress' => array(
'className' => 'Address',
),
);
When a user would have one address, I'd add a user_id as foreign key to the Address model and be done with it. But obviously, something has to be done differently for CakePhp to be able to distinguish between the address and the invoice address.
In my mind the solution is something like adding a address_id and invoice_address_id to the User table, but I can't seem to get it working in any way.
If you want to add in your user table the related fields then it is better to add them in the following form address_user_id and the invoice_address_user_id. Then you must have a belongsTo relation in your user model that looks like:
public $belongsTo = array(
'Address' => array(
'className' => 'Address',
'foreignKey' => 'address_user_id',
),
'InvoiceAddress' => array(
'className' => 'Address',
'foreignKey' => 'invoice_address_user_id',
),
);
So when you execute the following command $this->User->find('all'); the result will be
$result = array(0 =>
array('User' => array(...),
'Address' => array(...), // it will bring only one address row
'InvoiceAddress' => array(...) // it will bring only one address row
),
1 => ...
2 => ...
);
Then in your address Model the relationships you must add are:
public $hasOne = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'address_user_id',
),
'InvoiceUser' => array(
'className' => 'User',
'foreignKey' => 'invoice_address_user_id',
)
);

Cakephp Model ignores condition in belongsTo

I have 2 Models that are joined but not thrue the id's but with another field.
class Post extends AppModel{
public $useDbConfig = 'test';
public $actsAs = array('Containable');
public $belongsTo= array(
'User' => array(
'className' => 'User',
'foreignKey' => false,
'type' => 'inner',
'conditions' => array('User.field = Post.field')
));
}
But the cakephp is not connecting the 2 models correctly. To every Post it just gives the the first user (User with id 1). When I check the SQL-Statements the User statement is following:
SELECT `User`.`id`, `User`.`group_id`... FROM `users` AS `User` WHERE 1 = 1
Any ideas why this is not working?
I also tried joining the models manually:
$this->paginate = array(
'limit' => '15',
'joins' => array(
'INNER JOIN users User ON (User.field = Post.field)'
)
);
$posts= $this->paginate('Post');
Any ideas?
EDIT
I totally forgot to mention that these 2 tables are in different databases. Maybe there is the problem. But I had no problem joining tables over different databases so far.
EDIT
I was wrong about the join so I changed it from "belongsTo" to "hasOne" since a post can only be written by one user. But still no changes.
You can use the foreignKey parameter to any field, not necessarily the id:
Post model:
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'some_user_field'
)
);
User model:
public $hasMany = array (
'Post' => array (
'className' => 'Post',
'foreignKey' => 'some_user_field',
'dependent' => true
)
);
According to the book:
It is not mandatory to follow CakePHP conventions. You can easily
override the use of any foreignKey in your associations definitions.
Nevertheless, sticking to conventions will make your code less
repetitive and easier to read and maintain.
Otherwise, make joins manually:
$this->paginate = array(
'limit' => '15',
'joins' => array(
array(
'table' => 'users',
'alias' => 'User',
'type' => 'inner',
'conditions' => array('User.field = Post.field')
)
)
);
I found a solution although I don't understand why the others won't work. I put
$this->Post->primaryKey = 'field';
right before
$posts= $this->paginate('Post');
and now it works. Can anyone tell me why the other ways won't work?

which cakephp relationship should be used for groups of users? can haveMany use array for foreign_ID?

In my tennis application, my 'match' table has two players (obviously). I've used player1_id and player2_id as a way to track the user ids. I haven't included a user_id foreign key though.
There is also a 'user' table where I want to pull player's names from.
Because 'match' has more than one user and users have more than one model, I'm wondering if the following model configuration will work:
I've setup the user model like this:
var $name = 'User';
var $hasMany = array(
'Match' => array(
'className' => 'Match',
'foreignKey' => array( 'player1_id', 'player2_id'),
'dependent' => true,
)
and the match model like this:
var $name = 'Match';
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
)
I need to display the user first/last name for each player where user_id = player1_id or player2_id. Will this work? Can a foreign key use an array? And can a model operation use an 'or' when searching?
Or is there a better way to structure a table (like a match, or could be a group meeting) with more than one user?
Cheers,
Paul
I don't think an array as a foreign key on the User > Match relationship would work, but then again I have never tried. The single Match > User relationship with user_id as the foreign won't work though, since, as you said, that foreign id does not exist.
Conceptually the cleanest way would be a proper hasAndBelongsToMany relationship. After all, a match has many players, and players have many matches. So you're really looking at a many-to-many relationship.
To fake it with a belongsTo/hasMany relationship, you would need to do this:
// user model
var $hasMany = array(
'MatchAsPlayer1' => array(
'className' => 'Match',
'foreignKey' => 'player1_id',
),
'MatchAsPlayer2' => array(
'className' => 'Match',
'foreignKey' => 'player2_id',
)
);
// match model
var $belongsTo = array(
'Player1' => array(
'className' => 'User',
'foreignKey' => 'player1_id'
),
'Player2' => array(
'className' => 'User',
'foreignKey' => 'player2_id'
)
);
The ugly part is in the User model, where you'd receive related matches split into ['MatchAsPlayer1'] and ['MatchAsPlayer2']. You could do some trickery in the afterFind callback to merge those, but it's not a nice solution overall. Just go for the hasAndBelongsToMany. :)

How do I create a Unary association in CakePhp?

Is there a shortcut for creating Unary associations in Cake?
For example, a user is a friend of another user. I'm pretty sure it's going to violate cake's conventions if I try it the hard way and code the associations myself.
Cake has HABTM:
var $hasAndBelongsToMany = array(
'User' =>
array(
'className' => 'User',
'joinTable' => 'friends',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
'unique' => true
)
);
Will this work? A user model assoc to another user model.
Update:
How do I save the data now?
$this->data["Friend"] = $request["Requester"];
$this->data["Admirer"] = $request["Requestee"];
$this->Friend->create();
$this->Friend->save($this->data);
$request["Requester"] and $request["Requestee"] both hold objects of type User.
The HABTM rel is defined in the User model
var $hasAndBelongsToMany = array(
'Friend' => array(
'className' => 'Friend',
'joinTable' => 'friends',
'foreignKey' => 'user_id',
'associationForeignKey' => 'id'
),
'Admirer'=>array(
'className'=>'Friend',
'joinTable'=>'friends',
'foreignKey' => 'friend_id',
'associationForeignKey' => 'id',
)
);
All that happens is the $data->["Friend"]'s id is stored in the id column of the friends table
Here is a solution I use in an example application
Two tables are needed, users and followers. The important fields are User->id, Follower->user_id, Follower->friend_id.
I hope this snippet helps.
&lt?php
class User extends AppModel {
public $useTable='users';
public $hasAndBelongsToMany=array(
'Friend'=>array(
'className'=>'User',
'joinTable'=>'followers',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
),
'Admirer'=>array(
'className'=>'User',
'joinTable'=>'followers',
'associationForeignKey' => 'friend_id',
'foreignKey' => 'user_id',
),
);
}
-teh
Bjorn,
he is asking about User habtm User...
your join table should be users_users and the relation should look like this
var $hasAndBelongsToMany = array(
'Friend' =>
array(
'className' => 'UserUser',
'joinTable' => 'users_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
'unique' => true
)
);
i think that should do the trick
In CakePHP there are several variables in your model available to do that, like $hasMany, $belongsTo and $hasAndBelongsToMany. Please read the Cookbook for further explaination.. http://book.cakephp.org/view/78/Associations-Linking-Models-Together .
In your example, I think you need HABTM.

Categories