简体   繁体   English

Eloquent Laravel 模型上的 __construct

[英]A __construct on an Eloquent Laravel Model

I have a custom setter that I'm running in a __construct method on my model.我有一个自定义的 setter,我在模型的__construct方法中运行它。

This is the property I'm wanting to set.这是我要设置的属性。

    protected $directory;

My Constructor我的构造函数

    public function __construct()
    {
        $this->directory = $this->setDirectory();
    }

The setter:二传手:

    public function setDirectory()
    {
        if(!is_null($this->student_id)){
            return $this->student_id;
        }else{
            return 'applicant_' . $this->applicant_id;
        }
    }

My problem is that inside my setter the, $this->student_id (which is an attribute of the model being pulled from the database) is returning null .我的问题是在我的 setter 中, $this->student_id (这是从数据库中提取的模型的一个属性)返回null When I dd($this) from inside my setter, I notice that my #attributes:[] is an empty array.当我从我的 setter 中dd($this) ,我注意到我的#attributes:[]是一个空数组。
So, a model's attributes aren't set until after __construct() is fired.因此,直到__construct()被触发后才会设置模型的属性。 How can I set my $directory attribute in my construct method?如何在构造方法中设置$directory属性?

You need to change your constructor to:您需要将构造函数更改为:

public function __construct(array $attributes = array())
{
    parent::__construct($attributes);

    $this->directory = $this->setDirectory();
}

The first line ( parent::__construct() ) will run the Eloquent Model 's own construct method before your code runs, which will set up all the attributes for you.第一行( parent::__construct() )将在您的代码运行之前运行 Eloquent Model自己的构造方法,这将为您设置所有属性。 Also the change to the constructor's method signature is to continue supporting the usage that Laravel expects: $model = new Post(['id' => 5, 'title' => 'My Post']);此外,对构造函数方法签名的更改是继续支持 Laravel 期望的用法: $model = new Post(['id' => 5, 'title' => 'My Post']);

The rule of thumb really is to always remember, when extending a class, to check that you're not overriding an existing method so that it no longer runs (this is especially important with the magic __construct , __get , etc. methods).经验法则实际上是始终记住,在扩展类时,要检查您没有覆盖现有方法以使其不再运行(这对于魔术__construct__get等方法尤其重要)。 You can check the source of the original file to see if it includes the method you're defining.您可以检查原始文件的来源以查看它是否包含您正在定义的方法。

I wouldn't ever use a constructor in eloquent.我永远不会雄辩地使用构造函数。 Eloquent has ways to accomplished what you want. Eloquent 有办法完成你想要的。 I would used a boot method with an event listener.我会使用带有事件侦听器的引导方法。 It would look something like this.它看起来像这样。

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

    static::retrieved(function($model){
         $model->directory = $model->student_id ?? 'applicant_' . $model->applicant_id;
    });
}   

Here are all the model events you can use...以下是您可以使用的所有模型事件...

  • retrieved取回
  • creating创造
  • created创建
  • updating更新
  • updated更新
  • saving保存
  • saved已保存
  • deleting删除
  • deleted已删除
  • restoring恢复
  • restored恢复

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM