Larvel 5.8:如何在不附加整个关系的情况下使用静态$ appends?

时间:2019-05-08 07:38:40

标签: laravel eloquent

App\Customer有很多App\User

的典型情况

Customer.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Customer extends Model
{

    public function users()
    {
        return $this->hasMany('App\User');
    }

    public function getUserCountAttribute()
    {
        return $this->users->count();
    }
}

通过API将数据作为json提供,我正在使用

Customer::orderBy($order_by, $order_direction)->paginate(10);

例如获取(模拟数据)

{
    "id": 34,
    "name": "Angelita Bailey",
    "created_at": "2019-05-07 15:49:47",
    "updated_at": "2019-05-07 15:49:47",
    "deleted_at": null
},

如果我使用静态追加...

class Customer extends Model
{
    public $appends = [ 'userCount' ];
    ..
}

我不仅得到了 个userCount,还得到了users关系的完整数组!我不要这个...

{
    "id": 12,
    "name": "Carter Osinski",
    "created_at": "2019-05-07 15:49:47",
    "updated_at": "2019-05-07 15:49:47",
    "deleted_at": null,
    "userCount": 1,
    "users": [
        {
            "id": 25,
            "name": "ipurdy",
            "email": "schultz.joelle@example.com",
            "email_verified_at": null,
            "role": "CUSTOMER",
            "customer_id": 12,
            "created_at": "2019-05-07 15:49:49",
            "updated_at": "2019-05-07 15:49:49",
            "deleted_at": null
        }
    ]
},

问题

为什么会这样?

2 个答案:

答案 0 :(得分:3)

这是因为当您将关系作为属性访问时,它会加载该关系(如果尚未加载)。

如果您想在不加载关系的情况下获得计数,请改用Relationship方法:

public function getUserCountAttribute()
{
    return $this->users()->count();
}

当您将关系作为方法访问时,它将返回Relation的实例。这意味着您将有权访问查询生成器,因此可以在将执行计数查询的方法上调用count()方法。在您提供的示例中,您实际上是在集合上调用count()

答案 1 :(得分:2)

这是因为当您在此处致电$ this-> users时,您在计算项目数之前会关闭查询,因此最终您致电https://laravel.com/docs/5.8/collections#method-count而不是我们想要的口才。

public function getUserCountAttribute()
{
    return $this->users->count();
}

基本上,当您使用$ this-> users时,就像执行$ this-> users()-> get()一样,这样您就可以在对象上获得整个集合。 您可以解决此问题,只需在用户关系上添加方括号以保持查询构建器处于打开状态。

public function getUserCountAttribute()
{
    return $this->users()->count();
}

它应该为您找到工作。