带有连接和参数的Laravel Eloquent查询

时间:2014-07-08 20:31:55

标签: php join laravel-4 eloquent

我有一个项目列表(论文),并希望显示具有特定区域的所有论文。 现在我希望用户能够根据不同的属性过滤论文列表。

这些是表格/模型

Papers          
  id
  name
  author_id
  year
  paperQuality
  userRating

Authors         
  id
  name
  birthDate

Paper_areas     
  id
  paper_id
  area_id
  significance

Area            
  id
  name
  creationYear

我正在努力保持与Eloquent的关系。用户应该能够在paper.year,papers.paperQuality,papers.Rating,paper_areas_significance,area.creationYear

之后过滤。

这就是我现在所拥有的

$paper_areas_query = Paper_areas::join('areas', function($join){
    $join->on('areas.id', '=', 'paper_areas.area_id')
    ->where('areas.creationYear', '=', 2011);
});

$paper_areas_query->join('papers', function($join){
    $join->on('papers.id', '=', 'paper_areas.paper_id')
    ->where('papers.year', '=', 2011)
    ->where('papers.paperQuality', '=', 4)
    ->where('papers.userRating', '=', 5);
});

$paper_areas_query->join('authors', function($join){
    $join->on('authors.id', '=', 'papers.author_id');
});

$paper_areas_query->select('paper_areas.id', 'paper_areas.paper_id', 'paper_areas.area_id');
$paper_areas_query->orderBy('authors.name','asc');
$paper_areas_query->orderBy('papers.title','asc');
$paper_areas_query->groupBy('papers.id');

现在只显示2011年的论文,但我遇到了2个问题

  1. 如何使用从网址中获取的参数来重新计算年份?

  2. 如何以我拥有Paper_areas集合的方式过滤结果集?查看上面的代码,它似乎并不像其他代码那样“好”。

1 个答案:

答案 0 :(得分:0)

我会亲自修改您获取数据的方式,而不是在模型内部创建辅助函数。

在论文模型中,请考虑以下内容:

public function fromYear($year)
{
    return $this->where('year', '=', $year);
}

public function author()
{
    return $this->belongsTo('Author');
}

Areas模型中:

public function papers()
{
    return $this->belongsToMany('Paper', 'Paper_areas', 'id', 'topic_id');
}

然后,对于给定的Area实例,您可以获得该区域内所有论文的所有作者:

$id = 1;
$area = Area::find($id);
$papers = $area->papers->fromYear(2011)->get();
foreach($papers as $paper) {
    $author = $paper->author;
    // ...
}

至于从URL参数中获取年份,您可以在路线中执行以下操作:

Route::get('/my-route/{year}', 'MyController@action');

在你的控制器中有类似的东西:

class MyController
{
    public function action($year)
    {
        $area = /** get area instance **/;
        $papers = $area->papers->fromYear($year)->get();
    }
}

之后,点击路线/my-route/2014会将字符串2014传递给上面的action方法。对于所有其他过滤要求,您应该能够做同样的事情。