It should prevent the default delete, unless you have beforeDelete() defined in the model and forget to call the parent implementation of beforeDelete(). It may be a bug otherwise…
It should prevent the default delete, unless you have beforeDelete() defined in the model and forget to call the parent implementation of beforeDelete(). It may be a bug otherwise…
There is a way to override the beforeDelete() of model in the behavior?
something like
class SoftDeleteActiveRecordbehavior extends CActiveRecordbehavior {
/**
* @see CActiveRecordbehavior::beforeDelete()
*/
public function beforeDelete () {
$model = $this->getOwner();
$model->getOwner()->beforeDelete = $this->foo;
}
public function foo(){
}
}
No, what you did at first was fine, except I just noticed that Yii does not support canceling a delete from a behavior's beforeDelete(). This should be implanted IMHO. I'll create a ticket
Is there a way to run a method in a CModelbehavior before the execution of a find method in the model with this behavior?
Something like a beforeFind callback?
I want to do this to add merge some conditions to a query when a SoftDeletebehavior is attached to one model, to find only the records marked with the delete column equal to true
it doen’t work - the record is deleted. The code is being loaded however - if I put some rubbish into the file SoftDeleteActiveRecordBehavior.php it does come up with an error as intended.
However if I put the code
public function beforeDelete () {
$model = $this->getOwner();
$model->setAttribute('deleted', true);
$model->save();
return false;
}
directly in my model.php file it does work - ie my deleted field is set, and the record isn’t deleted.
What am I doing wrong? I’d like to implement the former rather than the latter.
I am trying to implement my version of SoftDeleteBehavoir. The main idea was to use beforeDelete to set "deleted" flag and use beforeFind to prevent "deleted" record from finding.
The code looks like:
class ARUndeletableBehavior extends CActiveRecordBehavior
{
public function beforeFind($event)
{
$criteria = new CDbCriteria;
$criteria->condition = "deleted = 0";
$this->owner->dbCriteria->mergeWith($criteria);
}
public function beforeDelete($event)
{
$this->owner->deleted = true;
$this->owner->save();
//prevent real deletion
$event->isValid = false;
}
}
The problem is that beforeFind invoked for regular ActiveRecords, but does not invoked for objects constructed using "with" statement. For example following code works ("deleted" records not returned and ARUndeletableBehavior::beforeFind is invoked):
$comment = Comment::model()->findbyPk($id);
But this does not ("deleted" records are returned and ARUndeletableBehavior::beforeFind is not invoked):
class SoftDeleteBehavior extends CActiveRecordBehavior
{
public $status='status';
public $valueDeleted = 'deletado';
public function beforeDelete($event)
{
$this->Owner->{$this->status} = $this->valueDeleted;
$this->Owner->save();
//prevent real deletion
$event->isValid = false;
}
public function deleteds() {
$this->Owner->getDbCriteria()->mergeWith(array(
'condition'=>$this->status."='$this->valueDeleted'"
));
return $this->Owner;
}
I recall reading that with() is implemented in CActiveFinder, so you might be able to override its behavior to censor the result set. I haven’t tried it though, so I don’t know how practical that would be. Good luck! In fact I hope you addressed this long ago.
Thanks for reply, Ivo. It seems CActiveFinder does not have behaviors. There are many ways to workaround this problem. In my case I added defaultScope() methods to my models to filter soft deleted records. Actually CActiveFinder is a good abstraction layer designed to be transparent and invisible, but here we have a case when this abstraction fails to be transparent.
P.S. I just checked CActiveFinder code again and there is a good chance that this problem is solved in Yii 1.1, because in Yii 1.0.9 there was no beforeFind() method call in CActiveFinder, but it is in Yii 1.1 RC.