Eloquent ORM 模型中添加自定义值

教程 lanceWan ⋅ 于 2016-12-28 14:05:50 ⋅ 最后回复由 lanceWan 2017-01-04 13:10:59 ⋅ 1157 阅读

我们都知道通过Laravel中数据库查询出来的模型对象都是基于数据库字段,今天给大家展示一个 Laravel Eloquent ORM 模型特性-附加值不存在于数据表中。

举个简单的栗子,一篇文章(posts表)对应有很多评论(comments表),我们获取文章的同时需要获取评论数量。通常的做法就是根据 ORM 的关联关系,获取评论数量:$post->comments()->count()

如果获取的是一个文章列表,那么最直接的办法就是 froeach 查询出来的文章,然后每篇文章获取评论数量;另外一种做法就是用 with 然后在闭包里面实现评论数量,至于怎么实现,我就不详细介绍了。Laravel 提供了一种更优雅的方式。

关联关系

class Post extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['title', 'text'];

    /**
     * 文章对应多条评论
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
}

上面代码没有什么特殊的,只是先声明一下关联关系,接下来会使用。接下来创建一个访问器,如果你还不清楚访问器是什么,建议你看一下Laravel官方文档:https://laravel.com/docs/5.3/eloquent-mutators

创建访问器

public function getCountCommentsAttribute()
{
    return $this->comments()->count();
}

这里的 getCountCommentsAttribute 方法名中 getAttribute 是固定写法,真正在模型中的名称是由 CountComments 决定,命名一般是驼峰写法,一个单词时在 ORM 模型中就是那个单词的小写,如果像 CountComments 这种方式在 ORM 模型会转化为 count_comments

创建访问器后,我们获取数据的时候 ORM 模型中并没有这个属性,因为Laravel并不会默认加上访问器的属性。

添加属性到ORM模型中

我们现在要做的很简单,我们想要在 ORM模型中获取到 count_comments 。只用简单的在 $appends 数组中添加属性名。

protected $appends = ['count_comments'];

OK,That was all!

简单的测试截图:

http://cache.iwanli.me/iwanli/image/QQ%E6%88%AA%E5%9B%BE20161228135846.jpg

查询出来的ORM中可以看到 appends 里面添加了 count_comments 属性。把这个 ORM 模型进行 toArray() 的时候机构就更加清晰了:

更多用法和扩展根据大家需要来就行了,这里只做一个抛砖引玉。这个知识点看到国外文章,需要翻墙,我就不贴出来了。

本帖已被设为精华帖!
本帖由 Summer 于 3个月前 加精
回复数量: 7
  • dope2008
    2016-12-28 20:12:10

    为什么不在文章表加一个字段,评论数量。你这样子性能呢?一个文章列表,如果每一个文章有10万条评论。

  • lanceWan 走得慢,但不后退...
    2016-12-28 22:40:31

    @dope2008 我这只是一个简单的例子,没有考虑任何东西。只是为了演示一下Laravel模型的自定义~~

  • lx1036 MOD Laravel,AWS,Angular
    2017-01-04 10:15:51

    Laravel提供了这个feature,Defining An Accessor

  • lanceWan 走得慢,但不后退...
    2017-01-04 10:35:15

    @lx1036 这个只能是数据库中已经存在的字段进行访问器的修改,日过定义的属性不存在数据库中的对应字段,查询出来是不会有人和效果的,必须要加到 $appends 数组中才行

  • lx1036 MOD Laravel,AWS,Angular
    2017-01-04 10:47:32

    @lanceWan 你说的是对的。。这个feature很常用,官方文档好像是没有写清楚。。自定义的属性就在$appends加上就行。。

  • zhuzhichao MOD Lalala Demacian !
    2017-01-04 13:07:41

    非常好的分享。方便的对数据内容进行调整更改等进行 append。

    但是要注意,绝对绝对不要在 append 里面添加一些耗时的操作或者需要资源的操作,比如数据库查询。否则无论何时,需不需要这个查询都会进行查询的。严重浪费资源。

    文中的例子建议使用 group by 进行统计操作。例子不太好,看过的人可能就会去在 append 里面添加数据库查询了 :smile:

  • lanceWan 走得慢,但不后退...
    2017-01-04 13:10:59

    @zhuzhichao 恩 是有点不恰当 :smile:

暂无评论~~
  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
Ctrl+Enter