我在项目中使用laravel,我想创建一个端点,该端点过滤并搜索Film
模型,并返回与所选过滤器选项匹配的电影集合,这些电影将由Options, Location and Age Rating
挑选用户。
我创建了一个查询,询问如何最初以symfony联接表(希望它是正确的),但不确定如何将其调整为更Laravel或雄辩。
电影模型
public function location(): BelongsTo
{
return $this->belongsTo(Location::class);
}
public function options(): BelongsToMany
{
return $this->belongsToMany(
Option::class,
'film_options',
'film_id',
'option_id'
);
}
public function ageRatings(): BelongsToMany
{
return $this->belongsToMany(
AgeRating::class,
'film_age_ratings',
'film_id',
'age_rating_id'
);
}
以学说查询
Select *
From films f
Join film_options fo on f.id = fo.film_id
Join options o on o.id = fo.option_id
Join film_age_ratings fa on f.id = fa.film_id
Join age_ratings a on a.id = fa.age_rating_id
Join location l on l.id = p.location_id
我该如何在laravel中编写此查询?
答案 0 :(得分:2)
要实现目标,可以同时使用when()和whereHas():
$films = Film
::when($request->input('first'), function ($query, $first) {
$query->whereHas('options', function ($query) use ($first) {
$query->where('first', $first);
});
})
->when($request->input('second'), function ($query, $second) {
$query->whereHas('options', function ($query) use ($second) {
$query->where('second', $second);
});
})
->when($request->input('age'), function ($query, $age) {
$query->whereHas('ageRatings', function ($query) use ($age) {
$query->where('age', $age);
});
})
->when($request->input('country'), function ($query, $country) {
$query->whereHas('locations', function ($query) use ($country) {
$query->where('country', $country);
});
})
->when($request->input('city'), function ($query, $city) {
$query->whereHas('locations', function ($query) use ($city) {
$query->where('city', $city);
});
})
->orderBy('updated_at', 'desc')
->get();
本质上,上面的意思是,当您提交非空值时,它将在查询中为该关系添加一个where子句
例如main
提交后,它将电影限制为只有主类别为提交值的电影。
此外,仅供参考,使用Eloquent时无需添加from(...)
方法。
一种限制行数的简单方法是将scopes添加到您的Film
模型中,例如
在您的Film
模型中:
public function scopeHasMain($query, $main)
{
$query->whereHas('options', function ($query) use($first) {
$query->where('first', $first);
});
}
那么您的when()
方法将是:
when($request->input('first'), function ($query, $first) {
$query->hasFirst($first);
})
答案 1 :(得分:0)
您可以使用whereHas
方法,如文档所示:https://laravel.com/docs/5.8/eloquent-relationships#querying-relationship-existence
示例:
use Illuminate\Database\Eloquent\Builder;
//...
$optionIds = [/* Option ids to filter by */];
$films = Film::whereHas('options', function (Builder $query) use ($optionIds) {
$query->whereIn('options.id', $optionIds);
})->get();