添加自定义属性Laravel / Eloquent模型加载?

我希望能够在Laravel/Eloquent模型加载时添加自定义属性/属性,类似于如何使用红豆的 $model->open()方法实现。

例如,目前,在我的控制器中,我有:

public function index()
{
$sessions = EventSession::all();
foreach ($sessions as $i => $session) {
$sessions[$i]->available = $session->getAvailability();
}
return $sessions;
}

这将是很好的能够省略循环,并有'available'属性已经设置和填充。

我尝试使用文档中描述的一些模型事件在对象加载时附加此属性,但到目前为止没有成功。

注:

  • 'available'不是底层表中的字段。
  • $sessions作为API的一部分作为JSON对象返回,因此在模板中调用类似$session->available()的东西是不可取的
306072 次浏览

如果你将你的getAvailability()方法重命名为getAvailableAttribute(),你的方法就变成了访问器,你可以直接在你的模型上使用->available读取它。

文档:https://laravel.com/docs/5.4/eloquent-mutators#accessors-and-mutators

EDIT:因为你的属性是“virtual”,所以默认情况下它不包含在对象的JSON表示中。

但我发现这个:自定义模型访问器没有处理时->toJson()调用?

为了强制在数组中返回属性,将其作为键添加到$attributes数组中。

class User extends Eloquent {
protected $attributes = array(
'ZipCode' => '',
);


public function getZipCodeAttribute()
{
return ....
}
}

我没有测试它,但是在当前的设置中尝试它应该是非常简单的。

该问题是由于ModeltoArray()方法忽略了与底层表中的列不直接相关的任何访问器。

正如Taylor Otwell提到的在这里,“这是故意的,出于性能原因。”然而,有一个简单的方法来实现这一点:

class EventSession extends Eloquent {


protected $table = 'sessions';
protected $appends = array('availability');


public function getAvailabilityAttribute()
{
return $this->calculateAvailability();
}
}

$ appendds属性中列出的任何属性都将自动包含在模型的数组或JSON形式中,前提是您已经添加了适当的访问器。

旧答案(Laravel版本<4.08):

我发现的最佳解决方案是重写toArray()方法,并显式设置属性:

class Book extends Eloquent {


protected $table = 'books';


public function toArray()
{
$array = parent::toArray();
$array['upper'] = $this->upper;
return $array;
}


public function getUpperAttribute()
{
return strtoupper($this->title);
}


}

或者,如果你有很多自定义访问器,循环遍历它们并应用它们:

class Book extends Eloquent {


protected $table = 'books';


public function toArray()
{
$array = parent::toArray();
foreach ($this->getMutatedAttributes() as $key)
{
if ( ! array_key_exists($key, $array)) {
$array[$key] = $this->{$key};
}
}
return $array;
}


public function getUpperAttribute()
{
return strtoupper($this->title);
}


}

拉拉维尔雄辩公司文档页的最后一件事是:

protected $appends = array('is_admin');

它可以自动用于向模型添加新的访问器,而不需要任何额外的工作,如修改::toArray()等方法。

只需创建getFooBarAttribute(...)访问器,并将foo_bar添加到$appends数组。

你可以在Model中使用setAttribute函数来添加一个自定义属性

我有类似的东西: 在我的模型中有一个属性图片,它包含了存储文件夹中文件的位置。 图像必须返回base64编码

//Add extra attribute
protected $attributes = ['picture_data'];


//Make it available in the json response
protected $appends = ['picture_data'];


//implement the attribute
public function getPictureDataAttribute()
{
$file = Storage::get($this->picture);
$type = Storage::mimeType($this->picture);
return "data:" . $type . ";base64," . base64_encode($file);
}

在我的例子中,创建一个空列并设置其访问器工作正常。 我的访问器填充用户的年龄从dob列。

. toArray()函数也有效
public function getAgeAttribute()
{
return Carbon::createFromFormat('Y-m-d', $this->attributes['dateofbirth'])->age;
}
在我的订阅模型中,我需要知道订阅是否暂停。 这是我是如何做到的

public function getIsPausedAttribute() {
$isPaused = false;
if (!$this->is_active) {
$isPaused = true;
}
}

那么在视图模板中,我可以使用 $subscription->is_paused来获取结果。< / p >

getIsPausedAttribute是设置自定义属性的格式,

并使用is_paused来获取或使用视图中的属性。

假设在用户表中有名为first_name和last_name的两列,您希望检索全名。你可以用下面的代码来实现:

class User extends Eloquent {




public function getFullNameAttribute()
{
return $this->first_name.' '.$this->last_name;
}
}

现在你可以得到全名为:

$user = User::find(1);
$user->full_name;
第一步:在$appends
中定义属性 步骤2:为该属性定义访问器 例子:< / p >
<?php
...


class Movie extends Model{


protected $appends = ['cover'];


//define accessor
public function getCoverAttribute()
{
return json_decode($this->InJson)->cover;
}