【问题标题】:Rails order results with multiple joins to same tableRails 对同一个表进行多次连接的排序结果
【发布时间】:2017-02-18 00:13:31
【问题描述】:

--编辑--

我想简化这个问题。 使用此模型结构:

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"

此外,我无法控制表的连接方式,因此无法定义表别名。

--更新--

我曾尝试使用以下方法从当前范围中提取别名:

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

但我仍然有点卡住,真的觉得应该有一个更简单的解决方案。

--更新--

pan 的答案在某些情况下有效,但我正在寻找一种更具动态性的解决方案。

【问题讨论】:

    标签: ruby-on-rails arel


    【解决方案1】:

    order方法中使用复数形式的关联名当前表名的串联作为表别名:

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

    【讨论】:

    • 我了解 rails 如何生成别名,但假设订单部分设置为范围,我不知道表已加入哪个订单。我可以使用该静态文本'pickup_jobs_packages.name desc',但如果首先加入了pickup_job,那将失败。我可以将订单文本更改为'jobs.name desc',但这将始终在第一次加入时订购。
    【解决方案2】:

    你可以试试这样的

    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)
    

    想法是在加入表格时创建自己的别名

    【讨论】:

    • 问题是我自己没有加入。我正在使用一种名为 filterrific 的宝石。我认为一定有办法从current_scope获取别名?
    • 我给了你赏金,因为你的答案更接近我所追求的,但这绝不是我正在寻找的理想解决方案。
    猜你喜欢
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多