Много ко многим построитель запросов laravel - PullRequest
0 голосов
/ 20 февраля 2020

Вот мой код запроса:

$apartments = DB::table('apartments')
    ->when($request->filled('wifi'), function ($query) {
        $query->join('apartment_service' , function($join){
            $join -> on('apartments.id' , '=' , 'apartment_service.apartment_id')
            ->where('apartment_service.service_id' , '=' , '1');
        });
    })
    ->when($request->filled('pool'), function ($query) {
        $query->join('apartment_service' , function($join){
            $join -> on('apartments.id' , '=' , 'apartment_service.apartment_id')
            ->where('apartment_service.service_id' , '=' , '2');
        });
    })
    ->when($request->filled('sea'), function ($query) {
        $query->join('apartment_service' , function($join){
        $join -> on('apartments.id' , '=' , 'apartment_service.apartment_id')
        ->where('apartment_service.service_id' , '=' , '3');
        });
    })
    ->when($request->filled('Terrace'), function ($query)  {
        $query->join('apartment_service' , function($join){
        $join -> on('apartments.id' , '=' , 'apartment_service.apartment_id')
        ->where('apartment_service.service_id' , '=' , '5');
        });
    })
    ->when($request->filled('sauna'), function ($query)  {
        $query->join('apartment_service' , function($join){
        $join -> on('apartments.id' , '=' , 'apartment_service.apartment_id')
        ->where('apartment_service.service_id' , '=' , '6');
        });
    })
    ->get();
        return response()-> json($apartments);

где моя ошибка с сводной таблицей?

Если я выбираю только одну службу, запрос работает, но когда я выбираю две или более сервисы запрос не работает.

1 Ответ

1 голос
/ 21 февраля 2020

Я считаю, что ваш запрос не работает, потому что он заканчивается примерно так:

SELECT * FROM apartments
INNER JOIN apartment_service ON apartments.id = apartment_service.apartment_id
INNER JOIN apartment_service ON apartments.id = apartment_service.apartment_id
WHERE
AND apartment_service.service_id = 3
AND apartment_service.service_id = 5
AND apartment_service.service_id = 6

Он потерпит неудачу, потому что в таблице apartment_service НЕТ записи, в которой есть единственное поле service_id из всех 3, 5 и 6!

Конечно, он будет работать с одним условием когда.

Я могу придумать два решения для решения вашей проблемы.

SOLUTON 1:

Позволяет переписать ваш запрос с контроллера:

class ApartmentsController extends Controller
{
    public function index()
    {
        return Apartment::join('apartment_service', 'apartments.id', '=', 'aparment_service.apartment_id')
            ->when($this->getServices(), function ($query) {
                return $query>whereIn('apartment_service.service_id', $this->getServices());
            })
            ->get();
    }

    protected function getServices()
    {
        $serviceIds = [];

        if (request()->filled('wifi')) {
            $serviceIds[] = 1;
        }

        if (request()->filled('pool')) {
            $serviceIds[] = 2;
        }

        if (request()->filled('sea')) {
            $serviceIds[] = 3;
        }

        if (request()->filled('terrace')) {
            $serviceIds[] = 5;
        }

        if (request()->filled('sauna')) {
            $serviceIds[] = 6;
        }

        return $serviceIds;
    }
}

РЕШЕНИЕ 2:

Я вижу какие-то ОТНОШЕНИЯ ОТ МНОГО К МНОГИМ между квартирой и обслуживанием. Итак, давайте определим отношения между этими двумя.

class Service extends Model
{
}

class Apartment extends Model
{
    public function services()
    {
        return $this->belongsToMany(Service::class, 'apartment_service');
    }
}

Затем из контроллера вы можете переписать что-то вроде:

class ApartmentsController extends Controller
{
    public function index()
    {
        return Apartment::when($this->getServices(), function ($query) {
            return $query>whereHas('services', function ($query) {
                $query->whereKeyIn($this->getServices());
            });
        })
        ->get();
    }
}
...