1
votes

I've got dataobjects called attribute and attribute set

The attribute set has this many_many relation to attribute

private static $many_many = array(
    'Attributes' => 'Attribute'
);

on attribute I've got this

private static $belongs_many_many = array(
    'Sets' => 'AttributeSet'
);

You can add attributes to an set either directly from the set or on the attribute. Now I need to know when a new attribute is added to a set, to update another content afterwards. I tried it with

public function onBeforeWrite(){
    parent::onBeforeWrite();

    if( $this->isChanged('Attributes') ){
        $this->Title = 'test';
    }

}

on the attribute set, but like presumed, it doesn't work, because the set get's not written if a new attribute is added.

Is there a way to do this?

Thank you in advance

2
Updated my answer (are you getting an alert of that as well?) - jberculo

2 Answers

1
votes

You can serialize in some way like json_encode the ManyManyList and store it in a private variable during the init stage, then you can deserialize it during the onBeforeWrite and check for differences.

It's not an efficient task, but I think it's the only way you have to achieve your goal.

1
votes

Couldn't you do something like this?

public function onBeforeWrite(){
    parent::onBeforeWrite();

    foreach($this->Attributes() as $attribute) {
        if($attribute->isChanged()) {
            $this->Title = 'test';
            break;
        }
    }
}

Update: I now realise that this will not work for objects that are deleted. Maybe it is an option to do things the other way around. So do an onBeforeDelete on the many_many objects that sets the field in the "parent(s)" and then saves it. You could even do this for onbeforeWrite as well...

update 2: It is a little unclear what you want. Do you want to know if the many_many objects have changed, regardless of when this happens, or do you just want to know if they change during the current page load?

isChanged only works when you load the object from the database, and then change something during the same cycle. The remainder of the current execution cycle, isChanged will return true. The next cycle, the object is reloaded, and isChanged returns back to false.

If you want to know if something changed since the last time you opened the parent object, you should store it in the database itself, or in the parent object (also in the db). This is quite easy, by just changing the parent object(s) with a boolean flag, and then saving again. If you want to track changes you need to implement something like @g4b0 suggests, or maybe try to add versioning to your objects. But the latter would probably force you to do a lot of custom coding.