【问题标题】:Many to many query builder laravel多对多查询生成器 laravel
【发布时间】:2020-02-21 18:48:20
【问题描述】:

这是我的查询代码:

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

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

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

【问题讨论】:

标签: php laravel query-builder


【解决方案1】:

我认为您的查询不起作用,因为它最终会变成:

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();
    }
}

【讨论】:

  • 查询返回getServices()不存在
  • @folipso 您使用的是第二种解决方案吗?如果是这样,请从第一个函数中复制 getServices() 函数。
猜你喜欢
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 2021-02-20
  • 2019-06-25
  • 2020-02-29
  • 2015-12-03
相关资源
最近更新 更多