Rails将多个连接的结果排序到同一表
问题描述:
- 编辑 -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--
锅的回答工作在某些情况下,但我要寻找一个解决方案,更加动感一些。
答
你可以尝试这样的事情
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)
想法是创建你自己的别名,而加入表
答
使用协会名称为多个和当前表名串联为一个表别名名称订单号方法:
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
问题在于我没有自己加入。我正在使用称为filterrific的宝石。我会认为必须有一种方法来从'current_scope'获取别名? – Rick
我已经给了你赏金,因为你的答案与我之后的答案更接近,但它绝不是我寻找的理想解决方案。 – Rick