首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在加载时向Laravel / Eloquent模型添加自定义属性?

在加载时向Laravel / Eloquent模型添加自定义属性?
EN

Stack Overflow用户
提问于 2013-06-21 18:13:21
回答 9查看 257.2K关注 0票数 258

我希望能够在加载Laravel/Eloquent模型时向其添加自定义属性/属性,这类似于使用RedBean's $model->open()方法可以实现的方式。

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

代码语言:javascript
复制
public function index()
{
    $sessions = EventSession::all();
    foreach ($sessions as $i => $session) {
        $sessions[$i]->available = $session->getAvailability();
    }
    return $sessions;
}

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

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

备注:

在底层table.

  • $sessions中,
  • 'available‘不是字段,而是作为
  • 的一部分作为JSON对象返回,因此在模板中调用像$session->available()这样的东西不是

的选项

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2013-06-22 19:51:10

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

正如Taylor Otwell提到的here,“这是有意的,并且是出于性能原因。”然而,有一种简单的方法可以实现这一点:

代码语言:javascript
复制
class EventSession extends Eloquent {

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

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

只要您添加了适当的访问器,$appends属性中列出的任何属性都将自动包含在模型的数组或JSON形式中。

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

我找到的最好的解决方案是覆盖toArray()方法,并显式设置属性:

代码语言:javascript
复制
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);    
    }

}

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

代码语言:javascript
复制
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);    
    }

}
票数 370
EN

Stack Overflow用户

发布于 2013-09-30 15:22:39

last thing on the Laravel Eloquent doc page为:

代码语言:javascript
复制
protected $appends = array('is_admin');

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

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

票数 130
EN

Stack Overflow用户

发布于 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数组中。

代码语言:javascript
复制
class User extends Eloquent {
    protected $attributes = array(
        'ZipCode' => '',
    );

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

我没有对其进行测试,但对于您在当前的设置中进行尝试来说,应该是相当简单的。

票数 41
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17232714

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档