【问题标题】:Fire Laravel events on touch在触摸时触发 Laravel 事件
【发布时间】:2019-02-01 18:05:03
【问题描述】:

这是我的场景: 我正在使用 Laravel 5.5.x。 我有两个模型,以一对多的方式链接。

class Artwork extends Model
{
   //It has timestamps
   protected $table = 'artworks';
   protected $fillable = [
        'artwork_category_id'
   ];
   public function artworkCategory()
    {
        return $this->belongsTo('App\Models\ArtworkCategory');
    }
}

class ArtworkCategory extends Model
{
    use SoftDeletes;

    protected $touches = ["artworks"];

    /**
     * @var string
     */
    protected $table = 'artwork_categories';
     protected $fillable = [
        'category_name',
        'acronym',
        'deleted_at'
    ];

    public function artworks()
    {
        return $this->hasMany('App\Models\Artwork');
    }
}

Touch 工作正常,所以当我更新艺术品类别时,相关的艺术品 updated_at 字段也会更新。

但我需要听每件艺术品上的“触摸”事件。 我尝试在 AppServiceProvider 的引导方法上插入“更新”侦听器,但它没有被触发。

Artwork::updated(function ($model){
            \Log::debug("HERE I AM");
        });

我尝试过使用观察者,但没有成功。

class ArtworkObserver
{
    public function updated(Artwork $artwork)
    {
        dd($artwork);
    }
}

AppServiceProvider 中的引导方法:

Artwork::observe(ArtworkObserver::class)

问题: 有人可以告诉我正确的方法吗?或者告诉我我哪里错了? 我还不够好,无法找到一个可以帮助我做到这一点的示例。

更新 我需要实现这一点,因为我必须“解雇”Scout 才能将 Elasticsearch 上的更新数据保存在 Artwork 索引上。

【问题讨论】:

  • 您想通过聆听Artwork 触摸来达到什么目的? $touches 不会为 Artwork 模型触发这些事件,因为模型永远不会被创建而是大规模更新。

标签: php laravel events laravel-5


【解决方案1】:

很可能$touches 使用批量更新,如果您查看Eloquent 的Events 部分,您会发现以下内容:

当通过 Eloquent 发布大规模更新时,saved 和 updated 模型事件将不会为更新的模型触发。这是因为在发布大规模更新时从未真正检索到模型。


我能想到的最好的方法是,当 ArtworkCategory 更新时,您手动更新 Artworks(而不是 $touches):

class ArtworkCategory extends Model
{
    use SoftDeletes;

     protected $fillable = [
        'category_name',
        'acronym',
        'deleted_at'
    ];

    public function artworks()
    {
        return $this->hasMany('App\Models\Artwork');
    }

    public static function boot()
   {
       parent::boot();

       static::updated(function($artworkCategory)
       {
            $artworkCategory->artworks->each(function($artwork) {
                $artwork->setUpdatedAt($artwork->freshTimestamp());
                $artwork->save(); /// Will trigger updated on the artwork model
            });
       });       
   }    
}

【讨论】:

  • 感谢您的解释。你知道是否有其他方法可以实现这一目标? (我已经更新了问题)
  • 谢谢 Orkhan,我的解决方案基于您的代码。如果您需要从多个模型开始触发更新的小提示:如果您从继承自 Model 的自定义类继承模型,您可以在那里编写引导方法并检查当前使用的模型是否与您想要的实体有关系更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
  • 2015-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-09
相关资源
最近更新 更多