2017-02-18 56 views
9

- 编辑 -Rails将多个连接的结果排序到同一表

我想简化此问题。 有了这个模型的结构:

has_one :pickup_job, class_name: 'Job', source: :job 
has_one :dropoff_job, class_name: 'Job', source: :job 

我想要做的是:

Package.joins(:dropoff_job, :pickup_job).order(pickup_job: {name: :desc}) 

这显然是无效的,应使用实际的语法是:

.order('jobs.name desc') 

然而rails加入表的方式意味着我无法确定表的别名是什么(如果有的话),并且这将按dropoff_job.name而不是pickup_job.name

irb(main):005:0> Package.joins(:dropoff_job, :pickup_job).order('jobs.name desc').to_sql 
=> "SELECT \"packages\".* FROM \"packages\" INNER JOIN \"jobs\" ON \"jobs\".\"id\" = \"packages\".\"dropoff_job_id\" INNER JOIN \"jobs\" \"pickup_jobs_packages\" ON \"pickup_jobs_packages\".\"id\" = \"packages\".\"pickup_job_id\" ORDER BY jobs.name desc" 

另外我不控制表是如何连接的,所以我无法定义表别名。

--UPDATE--

我有一出戏,试图用这样的提取从目前的范围别名:

current_scope.join_sources.select { |j| j.left.table_name == 'locations' } 

,但我还是有点卡住,真的感觉就像应该有一个更简单的解决方案一样。

--UPDATE--

锅的回答工作在某些情况下,但我要寻找一个解决方案,更加动感一些。

回答

0

你可以尝试这样的事情

Package.joins("INNER JOIN locations as dropoff_location ON dropoff_location.id = packages.dropoff_location_id INNER JOIN locations as pickup_location ON pickup_location.id = packages.pickup_location_id) 

想法是创建你自己的别名,而加入表

+0

问题在于我没有自己加入。我正在使用称为filterrific的宝石。我会认为必须有一种方法来从'current_scope'获取别名? – Rick

+0

我已经给了你赏金,因为你的答案与我之后的答案更接近,但它绝不是我寻找的理想解决方案。 – Rick

5

使用协会名称为多个当前表名串联为一个表别名名称订单号方法:

Package.joins(:dropoff_job, :pickup_job).order('pickup_jobs_packages.name desc') 
+1

我了解Rails如何生成别名,但假设订单部分设置为范围,并且我不知道表已加入哪个订单。我可以使用这个静态文本''pickup _jobs_packages.name desc'',但如果pickup pickup首先加入,那将会失败。我可以将订单文本更改为''jobs.name desc'',但这将始终在第一次加入时排序。 – Rick