Laravel Eloquent: Как фильтровать результаты связанных моделей?

#laravel #eloquent

#laravel #eloquent

Вопрос:

У меня есть таблицы в базе данных:

заказы

  --id
  --customer_id
  

клиенты

   --id
  --name
  --country_id
  

Страны

  --id
  --name
  

И следующие модели eloquent:

Order.php:

 <?php

namespace AppModels;

use IlluminateDatabaseEloquentModel;

class Order extends Model
{
   /**
     * @return IlluminateDatabaseEloquentRelationsBelongsTo
     */
    public function customer()
    {
        return $this->belongsTo('AppModelsCustomer');
    }
}
  

Клиент:

 <?php

namespace AppModels;

use IlluminateDatabaseEloquentModel;

class Customer extends Model
{
   /**
     * @return IlluminateDatabaseEloquentRelationsBelongsTo
     */
    public function country()
    {
        return $this->belongsTo('AppModelsCountry');
    }
}
  

Страна:

 <?php

namespace AppModels;

use IlluminateDatabaseEloquentModel;

class Country extends Model
{

}
  

Теперь мне нужно получить весь заказ, в котором название страны клиента похоже на ‘Uk’, одним SQL-запросом. Как я могу это сделать?

Ответ №1:

Следующее должно сработать:

 Order::whereHas('customer.country', function($innerQuery) {
    $innerQuery->where('countries.name', 'LIKE', 'Uk');
})->get();
  

Комментарии:

1. Вам не нужно countries.name , name достаточно одного. На самом деле я даже не уверен, работает ли это вообще с именем таблицы с префиксом к столбцу… И, возможно, использовать %UK% при использовании like .

2. «Я не уверен, работает ли это …» — Работает; вы можете использовать префикс или опустить его. В некоторых случаях это требуется из-за неоднозначности имен столбцов, но в большинстве случаев это не так.

3. Хорошо, имеет смысл. Особенно со столбцом с именем name . 🙂

Ответ №2:

Я не уверен, что это хороший способ мышления, но, возможно, я помог

 $orders = AppOrder::whereHas('customer.country', function ($query) {
        $query->where('name', 'like', 'UK%');
    })->get();
  

Комментарии:

1. $query->country()->where() не похоже на правильный синтаксис; Я думаю, вы можете просто отбросить country() , и это должно сработать. Хотя, order не имеет country связи, так что это было бы ошибкой.

2. Вы правы. Но после незначительных исправлений код должен заработать.

3. Проверьте здесь .