Larvel 5.8: Как использовать static $ append без добавления всей взаимосвязи? - PullRequest
0 голосов
/ 08 мая 2019

Классическая ситуация, когда 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();
    }
}

Служа данными как json через API, я использую

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
},

Если я использую static добавления ...

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 ]

3 голосов
/ 08 мая 2019

Это потому, что когда вы получаете доступ к отношению как к свойству, оно загружает отношение (если оно еще не загружено).

Если вы хотите получить счет без загрузки отношений, используйте метод отношениявместо этого:

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

Когда вы обращаетесь к связи как к методу, она возвращает экземпляр Relation.Это будет означать, что у вас будет доступ к построителю запросов, чтобы вы могли вызвать метод count () для того, который будет выполнять запрос подсчета.В приведенном вами примере вы фактически вызываете count () для коллекции.

2 голосов
/ 08 мая 2019

Это потому, что когда вы вызываете $ 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();
}

Это должно сделать работу за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...