在加载时向 Laravel/Eloquent 模型添加自定义属性? [英] Add a custom attribute to a Laravel / Eloquent model on load?

查看:52
本文介绍了在加载时向 Laravel/Eloquent 模型添加自定义属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够在加载 Laravel/Eloquent 模型时为其添加自定义属性/属性,类似于使用 RedBean 的 $model->open() 方法.

I'd like to be able to add a custom attribute/property to an Laravel/Eloquent model when it is loaded, similar to how that might be achieved with RedBean's $model->open() method.

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

For instance, at the moment, in my controller I have:

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

如果能够省略循环并且已经设置并填充了 'available' 属性,那就太好了.

It would be nice to be able to omit the loop and have the 'available' attribute already set and populated.

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

I've tried using some of the model events described in the documentation to attach this property when the object loads, but without success so far.

注意事项:

  • 'available' 不是基础表中的字段.
  • $sessions 作为 API 的一部分作为 JSON 对象返回,因此在模板中调用诸如 $session->available() 之类的东西不是'一个选项
  • 'available' is not a field in the underlying table.
  • $sessions is being returned as a JSON object as part of an API, and therefore calling something like $session->available() in a template isn't an option

推荐答案

问题是由 ModeltoArray() 方法忽略任何访问器引起的与基础表中的列没有直接关系.

The problem is caused by the fact that the Model's toArray() method ignores any accessors which do not directly relate to a column in the underlying table.

正如 Taylor Otwell 在此处所提到的,这是有意为之,也是出于性能原因."但是,有一种简单的方法可以实现这一目标:

As Taylor Otwell mentioned here, "This is intentional and for performance reasons." However there is an easy way to achieve this:

class EventSession extends Eloquent {

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

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

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

Any attributes listed in the $appends property will automatically be included in the array or JSON form of the model, provided that you've added the appropriate accessor.

旧答案(适用于 Laravel 版本 <4.08):

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

The best solution that I've found is to override the toArray() method and either explicity set the attribute:

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);    
    }

}

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

or, if you have lots of custom accessors, loop through them all and apply them:

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);    
    }

}

这篇关于在加载时向 Laravel/Eloquent 模型添加自定义属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆