Laravel 5.7: новый Accessor отлично работает, но не распознается в классе репозитория (неизвестный столбец), несмотря на добавление $ добавления в модель - PullRequest
2 голосов
/ 20 марта 2019

Итак, у меня есть class Order extends Model.

Я создал Accessor с именем requiresApproval, который возвращает true или false.

public function getRequiresApprovalAttribute(): bool
{
    if ($some_physical_column_from_db === 'does not matter') {
        return true;
    }

    return false;
}

Когда у меня есть Order модель и я звоню $order->requiresApproval Я получаю свое логическое значение. Все отлично работает.

Однако мне нужно, чтобы этот аксессор появился в списке атрибутов, потому что я хочу использовать его в своем классе репозитория в условии where в запросе.

Итак, основываясь на официальной документации, я добавил:

protected $appends = [
    'requires_approval',
];

, но когда я dd() моего ордера, этот атрибут отсутствует в списке атрибутов (хотя свойство $ appends указывает, что средство доступа есть).

enter image description here

Короче говоря:

Когда в моем хранилище я звоню:

public function getOrdersEligibleToBeSendToOptions(): Collection
{
    $columns = [
        '*',
    ];

    return $this->model
        ->where('status_uuid', '<>', OrderStatusesInterface::STATUS_COMPLETED)
        ->where('requiresApproval', '=', true) // this fails
        // ->where('requires_approval', '=', true) // this fails as well
        ->get($columns);
}

Я получаю:

enter image description here

Что я делаю не так?Как я могу использовать свой аксессор в классе репозитория?

Ответы [ 3 ]

0 голосов
/ 20 марта 2019

Красноречивые запросы работают с полями базы данных, но вы можете использовать свой аксессор после извлечения сбора из базы данных, как это.

Вот хорошая статья об этом:

https://medium.com/@bvipul/laravel-accessors-and-mutators-learn-how-to-use-them-29a1e843ce85

return $this->model
      ->where('status_uuid', '<>', OrderStatusesInterface::STATUS_COMPLETED)
      ->get($columns)
      ->filter(function ($row) {
           return $row->requires_approval === true;
       });
0 голосов
/ 20 марта 2019

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

class Order extends Model
{

    public function scopeRequiresApproval($query)
    {
        return $query->where('some_column', '>', 100);
    }
}

Тогда

return $this->model
        ->where('status_uuid', '<>', OrderStatusesInterface::STATUS_COMPLETED)
        ->requiresApproval()
        ->get($columns);
0 голосов
/ 20 марта 2019

ОК, это работает, но причина, по которой мне не нравится это решение, заключается в том, что только половина условий находится на уровне БД, а остальное - путем фильтрации того, что уже получено.

Если запрос вернет (скажем,) тысячи записей, а фильтр вернет лишь несколько из них, я лично считаю это огромной тратой ресурсов БД.

public function getOrdersEligibleToBeSendToOptions(): Collection
{
    $columns = [
        '*',
    ];

    $results = $this->model
        ->where('status_uuid', '<>', OrderStatusesInterface::STATUS_COMPLETED)
        ->get($columns);

    return $results->filter(function ($value, $key) {
        return $value->requiresApproval === false;
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...