Получить данные из нескольких объединений с помощью eloquent - PullRequest
0 голосов
/ 30 апреля 2020

Я разрабатываю проект для отслеживания поставок товара. Моя идея состояла бы в том, что одна доставка может go в разные места, и все эти места связаны едиными поездками.

Вот моя схема Eloquent:

class Delivery extends Model
{
    public function places()
    {
        return $this->hasMany(Place::CLASS, 'delivery_id');
    }

    public function trips()
    {
        // what should I do here?
    }
}
class Place extends Model
{
    public function delivery()
    {
        return $this->belongsTo(Delivery::CLASS, 'delivery_id');
    }
}
class Trip extends Model
{
    public function departurePlace()
    {
        return $this->belongsTo(Place::CLASS, 'departure_place_id');
    }

    public function arrivalPlace()
    {
        return $this->belongsTo(Place::CLASS, 'arrival_place_id');
    }
}

В основном я пытаюсь получить все поездки, связанные с одной доставкой. Или, как еще один способ сказать это, все поездки, которые соединяют все места, через которые должна пройти одна доставка. Это запрос SQL, который дает желаемый результат:

select distinct trip.*
from delivery
    join place on (place.delivery_id = delivery.id)
    join trip on (place.id = trip.arrival_place_id or place.id = trip.departure_place_id)

Я хотел бы иметь метод trips() в моей модели Delivery, который возвращает этот результат. Однако я не совсем понимаю, как добиться этого с помощью Eloquent.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2020

К сожалению, мы могли бы просто использовать метод union для достижения этой цели, но, похоже, это не работает для hasManyThrough отношений.

В любом случае, я думаю, Eloquent отношения не подразумеваются использоваться для достижения такого конкретного c запроса.

Вместо этого вы можете использовать Eloquent области для достижения этой цели.

Итак, основываясь на ответе @Saengdaet, мы можем написать два отношения и затем объединить их с scope:

(Кстати: я не знаю, почему вы сказали, что его код выдал ошибку ...)

class Delivery extends Model
{
    public function places()
    {
        return $this->hasMany(Place::class);
    }

    public function outboundTrips()
    {
        return $this->hasManyThrough(
            Trip::class, 
            Place::class,
            "delivery_id", // Foreign key on places table
            "departure_place_id", // Foreign key on trips table
        );
    }

    public function inboundTrips()
    {
        return $this->hasManyThrough(
            Trip::class, 
            Place::class,
            "delivery_id", // Foreign key on places table
            "arrival_place_id", // Foreign key on trips table
        );
    }

    public function scopeTrips($query)
    {
        $deliveriesWithTrips = $query->with(['outboundTrips', 'inboundTrips'])->get();

        $trips = [];
        $deliveriesWithTrips->each(function ($elt) use (&$trips) {
            $trips[] = $elt->inboundTrips->merge($elt->outboundTrips);
        });

        return $trips;
    }
}

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

 Delivery::where('id', $id)->trips();
0 голосов
/ 30 апреля 2020

Если вы хотите получить все поездки с использованием модели Delivery, вы можете использовать отношение `hasManyThrough ', которое предоставляет удобный ярлык для доступа к удаленным отношениям через промежуточное отношение.

Но вы должны выбрать, какое FK на вашей Trip модели вы будете использовать, чтобы связать ее

Вы можете сослаться на отношение "имеет много сквозных"

class Delivery extends Model
{
    public function places()
    {
        return $this->hasMany(Place::CLASS, 'delivery_id');
    }

    public function trips()
    {
        return $this->hasManyThrough(
                       Trip::Class, 
                       Place::Class,
                       "delivery_id", // Foreign key on places table
                       "departure_place_id", // Foreign key on trips table
                       "id", // Local key on deliveries table
                       "id" // Local key on places table
        );
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...