【问题标题】:How to listen for relation add events?如何监听关系添加事件?
【发布时间】:2017-04-20 12:06:46
【问题描述】:

我想在后端添加相关模型时调用一个函数。 这可以通过使用枢轴模型来实现,但在这种情况下必须有一些枢轴数据,否则不会触发枢轴模型事件。

我不需要任何数据透视数据,只需要监听关系添加事件。

【问题讨论】:

    标签: octobercms


    【解决方案1】:

    我认为这已解决,请参阅pull request 和 API Docs。他们为多对多关系添加了 4 个事件:afterAttach, afterDetach, beforeAttach and beforeDetach

    【讨论】:

    • 我需要这个来在附加后捕获事件并使用排序顺序更新我的数据透视表。非常感谢。你拯救了我的一天。我已经为此苦苦挣扎了好几个星期了。
    【解决方案2】:

    你问的很复杂,不容易做到。

    如果您查看关系管理器行为的函数onRelationManageCreate,您会发现它不会触发任何事件。

    我建议你扩展行为,用你自己的覆盖 onRelationManageCreate() 方法,并使用你自己的行为而不是关系管理器的行为。

    public MyRelationController extends RelationController 
    {
    
        public function afterRelationCreate()
        {
        }
    
        public function onRelationManageCreate() 
        {
           parent::onRelationManageCreate();
           $this->afterRelationCreate();
        }
    
    }
    

    这当然对于链接记录、在下拉列表、关系表单、复选框列表中进行选择没有任何作用。

    如果你真的想抓住它,你需要监听创建的模型的 onCreate 方法。

    【讨论】:

    • 当我用自己的扩展 RelationController 类时,我得到一个例外:Relation behavior used in MyClass does not have a model defined. 我错过了什么?
    • 你添加了 $relationConfig 吗?
    • 是的。我只是在实现数组中使用了我的自定义行为类。
    【解决方案3】:

    我猜这仅适用于“belongsTo”关系

    我认为关系被添加在那里,但它没有直接保存到数据库中,因为它会首先存储在不同的表中,以便我们可以拦截它。

    https://github.com/octobercms/october/blob/master/modules/backend/behaviors/RelationController.php#L1043

    https://github.com/octobercms/library/blob/762bb0a048d103db4d659d3749a02ea4877ba48f/src/Database/Traits/DeferredBinding.php#L36

    因此,如果您可以在“DeferredBinding”模型表上监听事件,您就可以实现您想要的。

    在 DeferredBinding 表中,它包含所有相关信息:

     Schema::create('deferred_bindings', function(Blueprint $table)
        {
            $table->engine = 'InnoDB';
            $table->increments('id');
            $table->string('master_type')->index();
            $table->string('master_field')->index();
            $table->string('slave_type')->index();
            $table->string('slave_id')->index();
            $table->string('session_key');
            $table->boolean('is_bind')->default(true);
            $table->timestamps();
        });
    

    如您所见,您可以在那里获得大量信息。

    use October\Rain\Database\Models\DeferredBinding as DeferredBindingModel;
    

    然后使用这个模型:

    DeferredBindingModel::saved(function($model) {
    
        // you can check relations etc if your parent model is foo
        // then you can check for which model this data is sotred
        // $model->master_type it will be you model's full name space
        // you can compare it 
    
        if($model->master_type == 'foo') {
            // your interception code here
        }
    }
    

    请让我们知道是否有帮助:)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多