Laravel добавление аксессора неожиданно также добавляет отношение к ответу - PullRequest
2 голосов
/ 22 февраля 2020

Спасибо, что нашли время помочь мне разобраться в этой проблеме.

У меня есть класс «Автомобиль», подобный следующему: (чтобы не усложнять, я удалил много методов и заполнений)

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

use App\Trip;

class Vehicle extends Model
{
    public $fillable = [
       ...
    ];

    protected $appends = [
        'LastTrip'
    ];

    public function trips()
    {
        return $this->hasMany(Trip::class);
    }

    public function getLastTripAttribute()
    {
        return $this->trips->last();
    }
}

Проблема в том, что когда я возвращаю экземпляр этого класса из контроллера. Он сериализует отношения 'поездки', так что каждая поездка находится в моем ответе.

Это, однако, происходит только тогда, когда я пытаюсь добавить средство доступа LastTrip. Если я изменю это на следующее, проблема не исчезнет

protected $appends = [
    #'LastTrip'
];

Я только пытаюсь заставить его сериализовать аксессор 'LastTrip'.

Я надеюсь, что сделал вопрос ясен, и, пожалуйста, дайте мне знать, если я смогу применить любую дополнительную информацию.

Спасибо за помощь.

Ответы [ 2 ]

3 голосов
/ 22 февраля 2020

Это происходит потому, что ваш аксессор выполняет следующие действия:

  1. Загрузка отношения полных отключений
  2. установка последнего элемента из коллекции отключений в качестве атрибута last_trip.

Измените свой код на следующий:

public function getLastTripAttribute()
{
    // If the relation is already loaded, avoid doing an extra SQL query
    if ($this->relationLoaded('trips')) {
        return $this->trips->last();
    // Otherwise, get the last trip from an SQL query.
    } else {
        return $this->trips()->orderByDesc('id')->first();
    }
}
2 голосов
/ 22 февраля 2020

EDITED:

Когда вы звоните $this->trips->last(), он выбирает все поездки, а затем назначает последнюю для LastTrip. Но если вы используете круглые скобки после «трипов», он должен получить только 1 строку из БД, попробуйте это:

public function getLastTripAttribute()
{
    return $this->trips()->latest()->first();
}

или

public function getLastTripAttribute()
{
    return $this->trips()->orderByDesc('id')->first();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...