Laravel:Eloquent Eager Loading 关系的选择

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43174190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 15:42:28  来源:igfitidea点击:

Laravel: Where selection for Eloquent Eager Loading relationship

phplaravellaravel-5eloquenteager-loading

提问by HelloWorld0815

I got two DB tables:

我有两个数据库表:

Posts

帖子

$table->increments('id');
$table->integer('country_id')->unsigned();
$table->foreign('country_id')->references('id')->on('countries');

Countries

国家

$table->increments('id');
$table->string('name', 70);

I use laravel as back-end. Now I want to implement filtering data for my front-end. So the user can select a country name and laravel should answer the request only with posts that have a country with the specified name.

我使用 laravel 作为后端。现在我想为我的前端实现过滤数据。因此用户可以选择一个国家/地区名称,而 Laravel 应该只使用具有指定名称的国家/地区的帖子来回答请求。

How could I add this condition to my existing pagination query? I tried this:

如何将此条件添加到我现有的分页查询中?我试过这个:

$query = app(Post::class)->with('country')->newQuery(); 
// ...
if ($request->exists('country')) {
        $query->where('country.name', $request->country);
}
// ...

... resulting in the following error:

...导致以下错误:

Column not found: 1054 Unknown column 'country.name' in 'where clause' (SQL: select count(*) as aggregate from `posts` where `country`.`name` = Albania)

回答by alithedeveloper

whereHas method accepts parameter as per Laravel code base,

whereHas 方法根据 Laravel 代码库接受参数,

 /**
 * Add a relationship count / exists condition to the query with where clauses.
 *
 * @param  string  $relation
 * @param  \Closure|null  $callback
 * @param  string  $operator
 * @param  int     $count
 * @return \Illuminate\Database\Eloquent\Builder|static
 */
public function whereHas($relation, Closure $callback = null, $operator = '>=', $count = 1)
{
    return $this->has($relation, $operator, $count, 'and', $callback);
}

so Changing the code a little as,

所以稍微改变代码,

$query = ""    

if ($request->has('country'){
$query = Post::with("country")->whereHas("country",function($q) use($request){
    $q->where("name","=",$request->country);
})->get()
}else{
    $query = Post::with("country")->get();
}

By the way above code can be a little simplified as follow;

顺便说一下,上面的代码可以简化如下;

$query = ""    

if ($request->has('country'){
  $query = Post::with(["country" => function($q) use($request){
  $q->where("name","=",$request->country);
}])->first()
}else{
  $query = Post::with("country")->get();

}

}

回答by oseintow

$query = ""    

if ($request->has('country'){
    $query = Post::with("country")->whereHas("country", function($q) use($request){
        $q->where("name","=",$request->country);
   })->get()
}else{
    $query = Post::with("country")->get();
}