Reputation: 173
I have the following setup:
Models:
Team
Task
Change
TasksTeam
TasksTeam
is a hasManyThrough, that associates teams to tasks. Change
is used to record changes in the details of tasks, including when teams are attached/detached (i.e. through records in TasksTeam
).
TasksTeam
also cascades deletes of Task
. If a task is deleted, all related team associations should also be deleted.
When a TasksTeam
is deleted, it means a team has left a task, and I'd like to record a Change
for that. I'm using the TasksTeam afterDelete()
to record teams leaving. In the TasksTeam beforeDelete
I save the data to $this->predelete
so it'll be available in the afterDelete()
.
Here is the non-working code in TasksTeam
:
public function afterDelete(){
$team_id = $this->predelete['TasksTeam']['team_id'];
$task_role_id = $this->predelete['TasksTeam']['task_role_id'];
$task_id = $this->predelete['TasksTeam']['task_id'];
// Wanted: only record a change if the task isn't deleted
if($this->Task->exists($task_id)){
$this->Task->Change->removeTeamFromTask($task_id, $team_id, $task_role_id);
}
return true;
}
Problem:
When a task is deleted, the delete cascades to TasksTeam
correctly. However, a change will be recorded even if the Task is deleted. From another answer to something similar on SO, I think the reason is that the callbacks are called before Model:del()
, meaning the task hasn't yet been deleted when it hits TasksTeam
afterDelete()
Question
How can I successfully save a Change
only if the task isn't deleted?
Thanks in advance.
Upvotes: 1
Views: 65
Reputation: 173
Using the suggestion from @James Dunne I ended up adding a tinyint field to the Task
model called is_deleted
and simply set this boolean true in the Task
beforeDelete()
. I then check for this flag and only save a Change
if the flag is boolean false. It seems wasteful to add a field for something that is only affected just before the record is deleted, but for my purposes it works fine. I think a "real solution" would involve the Cake Events System , avoiding the need for chained callbacks.
Upvotes: 0
Reputation: 770
If the callbacks are getting called before the actual delete, I see maintaining an assoc. array of flags with task IDs as keys, or a set of task IDs, which are added when afterDelete
is called on Task
. Then you could create a method in Task
, such as isDeleting
or similar, which queries the array, to tell you if the task is in the process of being deleted.
Upvotes: 1