【问题标题】:Laravel model relationships and model eventsLaravel 模型关系和模型事件
【发布时间】:2015-10-25 09:34:39
【问题描述】:

我目前正在构建一个通知系统,通知通过模型事件传递。一些通知取决于模型关系发生的事情。

示例:我有一个与用户有一对多关系的项目模型,

public function projectmanager() {
    return $this->belongsToMany('User', 'project_managers');
}

我想在我的项目模型事件中监控这种关系的变化。目前,我正在通过以下方式做到这一点,

$dirtyAttributes = $project->getDirty();
foreach($dirtyAttributes as $attribute => $value) {
   //Do something
}

这是在模型的::updating 事件中运行的,但只查看模型属性而不是任何关系数据,是否可以获取旧的关系数据和新的关系数据进行比较和处理?

【问题讨论】:

  • 你找到解决办法了吗?
  • 我认为这不可能。因为具有关系的数据具有不同的保存模型(在您的情况下可能有ProjectManager模型对吗?)。虽然您可以发布您如何尝试保存Project 模型吗?你是和亲戚一起保存还是单独保存?
  • 您始终可以在您的模特活动中get the request。我觉得这很奇怪,但它确实有效。

标签: php laravel eloquent relational-database


【解决方案1】:

您应该为此使用observer class

this SO answer 已经相当简单且很好地涵盖了这一点,尽管该答案使用了一个稍旧的方法,其中类本身需要调用其观察者。当前版本的文档(截至本答案为 5.3)建议在您的应用程序服务提供商中注册观察者,在您的示例中看起来类似于:

<?php
namespace App\Providers;

use App\Project;
use App\Observers\ProjectObserver;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Project::observe(ProjectObserver::class);
    }
}

为了评估仍在关系数据库中的新模型值和旧值之间的差异,Laravel 提供了两种方法:getDirty()getOriginal()

所以你的观察者看起来像:

<?php

namespace App\Observers;

use App\Project;

class ProjectObserver
{
    /**
     * Listen to the Project updating event.
     *
     * @param  Project $project
     * @return void
     */
    public function updating(Project $project)
    {
        $dirtyAttributes = $project->getDirty();
        $originalAttributes = $project->getOriginal();
        // loop over one and compare/process against the other
        foreach ($dirtyAttributes as $attribute => $value) {
            // do something with the equivalent entry in $originalAttributes
        }
    }
}

【讨论】:

  • 我知道已经过去了 3 年,但我有点困惑为什么这个答案被接受了。它没有解决问题,即如何获取 related 字段的脏值/原始值。 getDirty 和 getOriginal 不包含有关关系的任何信息(例如外键除外)。
  • @CharlesWood 对关系本身的更改由外键确定,如果更改(即哪个用户更改为项目经理),它将成为原始/脏值的一部分。如果您想检测相关模型的更改(例如,您想知道作为经理的用户是否更改了他们的名字?)那么您将有一个 User 模型的观察者并对那里的更改做一些事情。如果您出于某种原因想要操纵项目以观察相关模型的变化,您可以使用getRelations()relationsToArray()。也许getTouchedRelations(),取决于。
  • 哦,当然!感谢您为我拼写出来。
猜你喜欢
  • 2013-10-28
  • 2016-03-21
  • 1970-01-01
  • 2019-04-04
  • 1970-01-01
  • 2023-02-16
  • 1970-01-01
相关资源
最近更新 更多