【问题标题】:Laravel Eloquent query with joins and parameters带有连接和参数的 Laravel Eloquent 查询
【发布时间】:2014-07-08 20:31:55
【问题描述】:

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

这些是表格/模型

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 的相关性。用户应该能够在papers.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. 如何使用从 url 获取的参数来替换年份?

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

【问题讨论】:

  • Paper_areas 表中的topic_id 列是Areas 表的键吗?
  • 是的,对不起 - 我已经重命名了

标签: php join laravel-4 eloquent


【解决方案1】:

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

在您的论文模型中,考虑如下内容:

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 方法。您应该能够对所有其他过滤要求执行基本相同的操作。

【讨论】:

  • 感谢您的想法,我应该记住这一点,但我看到的“问题”是用户应该能够在 paper_areas.significance 之后进行过滤。我认为在这个查询中不可能做这样的事情。在变量 $papers 中是论文的集合。如果我使用belongsToMany,似乎没有可能达到这个意义,因为这个属性将无法访问,或者以某种方式?
猜你喜欢
  • 1970-01-01
  • 2021-02-11
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 2015-08-19
  • 2015-04-28
  • 2021-05-12
  • 2014-12-06
相关资源
最近更新 更多