php Eloquent Laravel 模型上的 __construct
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30502922/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
A __construct on an Eloquent Laravel Model
提问by Nathan Lochala
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
.
When I dd($this)
from inside my setter, I notice that my #attributes:[]
is an empty array.
So, a model's attributes aren't set until after __construct()
is fired. How can I set my $directory
attribute in my construct method?
我的问题是,在我的 setter 中,$this->student_id
(这是从数据库中提取的模型的一个属性)正在返回null
. 当我dd($this)
从我的 setter 内部时,我注意到 my#attributes:[]
是一个空数组。
因此,模型的属性直到__construct()
被触发后才会设置。如何$directory
在我的构造方法中设置我的属性?
回答by alexrussell
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. 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']);
第一行 ( parent::__construct()
) 将Model
在您的代码运行之前运行 Eloquent自己的构造方法,这将为您设置所有属性。此外,对构造函数方法签名的更改是继续支持 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). You can check the source of the original file to see if it includes the method you're defining.
经验法则真的是要永远记住,扩展一个类时,要检查你没有覆盖现有的方法,使其不再运行(这一点尤其重要与魔法__construct
,__get
等方法)。您可以检查原始文件的来源以查看它是否包含您正在定义的方法。
回答by Jed Lynch
I wouldn't ever use a constructor in eloquent. Eloquent has ways to accomplished what you want. I would used a bootmethod with an event listener. It would look something like this.
我永远不会雄辩地使用构造函数。Eloquent 有办法完成你想要的。我会使用带有事件侦听器的引导方法。它看起来像这样。
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
- 取回
- 创造
- 创建
- 更新
- 更新
- 保存
- 已保存
- 删除
- 已删除
- 恢复
- 恢复