【问题标题】:Silverstripe 3 - Detect changes on many_many relationSilverstripe 3 - 检测 many_many 关系的变化
【发布时间】:2014-07-15 22:29:43
【问题描述】:

我有名为 attributeattribute set 的数据对象

属性集与属性有这种many_many关系

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

属性我有这个

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

您可以直接从集合中或在属性上向集合添加属性。 现在我需要知道何时将新属性添加到集合中,以便之后更新另一个内容。我试过了

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

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

}

在属性集上,但就像假设的那样,它不起作用,因为如果添加了新属性,则不会写入set get。

有没有办法做到这一点?

提前谢谢你

【问题讨论】:

  • 更新了我的答案(你是否也收到了警报?)

标签: silverstripe


【解决方案1】:

您可以在初始化阶段以 json_encode 之类的方式序列化 ManyManyList 并将其存储在私有变量中,然后您可以在 onBeforeWrite 期间对其进行反序列化并检查差异。

这不是一项高效的任务,但我认为这是实现目标的唯一途径。

【讨论】:

  • 你能用一个小代码示例更新你的答案吗?
  • 我使用这种方法将“旧”属性作为字符串存储在数据库中,然后将其与新属性进行比较。
【解决方案2】:

你不能这样做吗?

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

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

更新:我现在意识到这不适用于已删除的对象。也许反过来做事也是一种选择。因此,对许多对象执行 onBeforeDelete 操作,将字段设置为“parent(s)”,然后保存。你甚至可以为 onbeforeWrite 执行此操作...

更新 2: 有点不清楚你想要什么。您想知道 many_many 对象是否发生了变化,无论何时发生,还是只想知道它们在当前页面加载期间是否发生了变化?

isChanged 仅在您从数据库加载对象,然后在同一周期内更改某些内容时才有效。当前执行周期的剩余部分,isChanged 将返回 true。下一个循环,对象被重新加载,isChanged返回false。

如果您想知道自上次打开父对象以来是否发生了变化,您应该将其存储在数据库本身或父对象中(也在数据库中)。这很容易,只需使用布尔标志更改父对象,然后再次保存。如果您想跟踪更改,您需要实现类似@g4b0 建议的内容,或者尝试为您的对象添加版本控制。但后者可能会迫使您进行大量自定义编码。

【讨论】:

  • 我试试看。但我需要展位。我需要知道是否从集合中删除了属性以及是否将属性添加到集合中。我需要知道删除和添加了哪些属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-05
  • 2013-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多