【问题标题】:Execute code when Eloquent model is retrieved from database从数据库中检索 Eloquent 模型时执行代码
【发布时间】:2013-09-18 23:15:29
【问题描述】:

我有一个 Eloquent 模型。每当从数据库中检索到它时,我都想检查是否满足条件并在这种情况下设置模型属性。

编辑:我最初认为 restoring 事件将是放置相关逻辑的正确位置,但正如 Tyler Crompton 在下面指出的那样,restoring 在恢复软删除记录之前被触发。

【问题讨论】:

标签: php events laravel eloquent


【解决方案1】:

您有两个有效的选择:

如果我是你,我会选择第一个选项,我会这样做:

<?php namespace \Illuminate\Database\Eloquent;

abstract class LoadingModel extends Model {

    /**
     * Register a loaded model event with the dispatcher.
     *
     * @param  \Closure|string  $callback
     * @return void
     */
    public static function loaded($callback)
    {
        static::registerModelEvent('loaded', $callback);
    }

    /**
     * Get the observable event names.
     *
     * @return array
     */
    public function getObservableEvents()
    {
        return array_merge(parent::getObservableEvents(), array('loaded'));
    }

    /**
     * Create a new model instance that is existing.
     *
     * @param  array  $attributes
     * @return \Illuminate\Database\Eloquent\Model|static
     */
    public function newFromBuilder($attributes = array())
    {
        $instance = parent::newFromBuilder($attributes);

        $instance->fireModelEvent('loaded', false);

        return $instance;
    }

}

只需确保有问题的模型是LoadingModule 的子类。我已经确认这是可行的,因为我找到了一个很好的用例。旧版本的 PHP 将 MySQL 值作为字符串返回。通常,PHP 会在数值运算中默默地将它们转换为它们各自的数值类型。但是,转换为 JSON 不被视为数字操作。 JSON 值表示为字符串。这可能会给我的 API 的客户端带来问题。所以我在我的模型中添加了一个loaded 事件,以将值转换为正确的类型。

【讨论】:

  • 谢谢!!它确实有效,而且很奇怪他们不会将此事件添加到 eloquent 模型中:所有事物都有一个事件,但不是从数据库中检索数据!谢谢! :)
  • @AlessioPeriloso,我相信他们不想要它,因为在已经很重的框架上,这只是每个模型的一个额外函数调用。没有足够的用例需要它。您可以提出的用例可以通过替代(尽管语义较少)的方式来解决。
  • 选项 3:在您的具体模型中覆盖 newFromBuilder 并在事件处理程序中执行您想做的任何事情。相当老套,但对于一次性使用可能已经足够了。
【解决方案2】:

您可以在进出时执行此操作。似乎您希望将其存储在数据库中,因此您可以使用 mutators。

class Foo extends Eloquent {

    public function setBAttribute($value)
    {
        if ($this->attributes['a'] == $this->attributes['b']) {
            $this->attributes['b'] = 1;
        }
    }    
}

一旦设置了B,它将检查A,并将1 存储在B 中。

旁注:注意集合和属性之间的B

【讨论】:

    【解决方案3】:

    我认为这是您可以使用的最佳选择。

    从数据库中检索现有模型时,将触发检索事件。例如,如果您的应用程序中有一个用户模型,您必须在用户模型中定义如下代码。

    self::retrieved(function (self $model){
       //all your code here
    });
    

    【讨论】:

      猜你喜欢
      • 2021-01-18
      • 1970-01-01
      • 2013-09-06
      • 2017-07-07
      • 2012-03-12
      • 1970-01-01
      • 2013-12-22
      • 2016-12-06
      • 1970-01-01
      相关资源
      最近更新 更多