Reputation: 11725
I have a Comment
Model that I am using to store comments for both Goal
s and Note
s.
The current implementation has a GoalComment
Model and a NoteComment
Model, each of which extends Comment
, and the Comment
's beforeFind
does the following:
$queryData['conditions'][$this->name . '.' . $this->__type_field] = $this->name;
which basically sets the type
field of the Comment
Model to either GoalComment
or NoteComment
, depending on which of those classes is performing a find
.
This implementation has worked up until now, where I want to delete comments. Below is the Model association for Comments in Goals:
var $hasMany = array(
'Comment' => array(
'className' => 'GoalComment',
'foreignKey' => 'object_id'
)
);
And in my beforeDelete, where I want to remove all comments associated with the goal, I have:
$this->Comment->deleteAll(array('object_id' => $this->id));
But I get the following SQL error:
SQL Error: 1054: Unknown column 'GoalComment.type' in 'where clause' [CORE\cake\libs\model\datasources\dbo_source.php, line 525]
Query: SELECT `Comment`.`id` FROM `comments` AS `Comment` LEFT JOIN `users` AS `Poster` ON (`Comment`.`poster_id` = `Poster`.`id`)
LEFT JOIN `goals` AS `Goal` ON (`Comment`.`object_id` = `Goal`.`id`)
WHERE `object_id` = 52 AND `GoalComment`.`type` = 'GoalComment'
This is happening because of the beforeFind
action I described before, which adds the GoalComment.type = 'GoalComment'
. This has made me rethink the whole approach to the situation.
So my question is how should this relationship be re-implemented? My best idea is to scrap the beforeFind
in Comment
and simply remake the $hasMany
relationship to be:
var $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'object_id',
'conditions' => array('Comment.type = "GoalComment"')
)
);
This would extract all of the thinking from the Comment
Model, and it just seems more natural to me.
Do you have an idea for a better implementation, or should I go with the one above? Thanks!
Upvotes: 3
Views: 726
Reputation: 29131
I think you're correct in realizing that you've been over-thinking the associations.
The "normal" way for this type of relationship is to simply use the fields model
and foreign_key
in your comments table.
//Comment model
public $belongsTo = array(
'Goal' => array(
'className' => 'Goal',
'foreignKey' => 'foreign_key',
'conditions' => array('Comment.model' => 'Goal')
,
'Note' => array(
'className' => 'Note',
'foreignKey' => 'foreign_key',
'conditions' => array('Comment.model' => 'Note')
)
);
//Goal model
public $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'foreign_key',
'conditions' => array('Comment.model' => 'Goal')
)
);
//Note model
public $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'foreign_key',
'conditions' => array('Comment.model' => 'Note')
)
);
Upvotes: 4