我希望能够在加载Laravel/Eloquent模型时向其添加自定义属性/属性,这类似于使用RedBean's $model->open()
方法可以实现的方式。
例如,目前在我的控制器中,我有:
public function index()
{
$sessions = EventSession::all();
foreach ($sessions as $i => $session) {
$sessions[$i]->available = $session->getAvailability();
}
return $sessions;
}
如果能够省略循环,并且已经设置和填充了“available”属性,那就太好了。
我已经尝试使用文档中描述的一些模型事件在对象加载时附加此属性,但到目前为止还没有成功。
备注:
在底层table.
$sessions
中,$session->available()
这样的东西不是的选项
发布于 2013-06-22 19:51:10
该问题是由于Model
的toArray()
方法忽略了与底层表中的列不直接相关的任何访问器造成的。
正如Taylor Otwell提到的here,“这是有意的,并且是出于性能原因。”然而,有一种简单的方法可以实现这一点:
class EventSession extends Eloquent {
protected $table = 'sessions';
protected $appends = array('availability');
public function getAvailabilityAttribute()
{
return $this->calculateAvailability();
}
}
只要您添加了适当的访问器,$appends属性中列出的任何属性都将自动包含在模型的数组或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);
}
}
发布于 2013-09-30 15:22:39
last thing on the Laravel Eloquent doc page为:
protected $appends = array('is_admin');
它可以自动用于向模型中添加新的访问器,而无需任何额外的工作,如修改::toArray()
等方法。
只需创建getFooBarAttribute(...)
访问器并将foo_bar
添加到$appends
数组。
发布于 2013-06-21 21:06:40
如果您将getAvailability()
方法重命名为getAvailableAttribute()
,您的方法将成为一个访问器,并且您将能够直接在模型上使用->available
读取它。
文档:https://laravel.com/docs/5.4/eloquent-mutators#accessors-and-mutators
编辑:由于您的属性是“虚拟的”,因此默认情况下,它不会包含在对象的JSON表示中。
但我发现了这个:Custom model accessors not processed when ->toJson() called?
为了强制在数组中返回属性,请将其作为键添加到$attributes数组中。
class User extends Eloquent {
protected $attributes = array(
'ZipCode' => '',
);
public function getZipCodeAttribute()
{
return ....
}
}
我没有对其进行测试,但对于您在当前的设置中进行尝试来说,应该是相当简单的。
https://stackoverflow.com/questions/17232714
复制相似问题