繁体   English   中英

多对多查询构建器laravel

[英]Many to many query builder laravel

这是我的查询代码:

$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);

我的数据透视表错误在哪里?

如果我只选择一项服务,则查询有效,但当我选择两项或多项服务时,查询无效。

我相信您的查询不起作用,因为它最终类似于:

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 表上没有记录具有所有3、5 和6 的单个service_id 字段!

当然,它会与单个 when 条件一起使用。

我可以想到两种解决方案来解决您的问题。

解决方案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();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM