Arel:使用符号的左外连接

Chu*_*ckE 5 sql activerecord arel ruby-on-rails-3

我有这个用例,我从某个模型获得符号化的深层关联,我必须执行涉及使用外连接的某些查询.如何在不用手写完整SQL的情况下做到这一点?

答案我不想要: - 使用包括(不能很好地解决深层关联(.includes(:cars => [:windows,:engine => [:ignition] .....意外地工作)我不喜欢我不想要它的副作用 - 自己编写SQL(对不起,它是2013,跨数据库支持等等......,我获取的对象是read_only,更多的副作用)

我想要一个Arel解决方案.我知道使用模型中的arel_table我可以构造SQL表达式,还有一个用于连接的DSL,但不知怎的,我不能在模型的连接方法中使用它:

car = Car.arel_table
engine = Engine.arel_table

eng_exp = car.join(engine).on(car[:engine_id].eq(engine[:id]))
eng_exp.to_sql #=> GOOD! very nice!
Car.joins(eng_exp) #=> Breaks!!
Run Code Online (Sandbox Code Playgroud)

为什么这不起作用超出了我的范围.我不知道到底缺少什么.但它与我现在的解决方案最接近.如果有人可以帮我完成我的例子,或者给我一个很好的解决方法,或者告诉我什么时候Rails包含这样一个明显必要的功能将会有我永远的感激之情.

MrT*_*rus 7

我发现了一篇旨在解决这个问题的博客文章:http://blog.donwilson.net/2011/11/constructing-a-less-than-simple-query-with-rails-and-arel/

基于此(以及我自己的测试),以下内容适用于您的情况:

car = Car.arel_table
engine = Engine.arel_table   

sql = car.project(car[Arel.star])
        .join(engine, Arel::Nodes::OuterJoin).on(car[:engine_id].eq(engine[:id]))

Car.find_by_sql(sql)
Run Code Online (Sandbox Code Playgroud)


Dav*_*ose 6

这是一个老问题,但为了通过搜索引擎找到它的人的利益:

如果你想要传递的东西.joins,你可以使用.create_join.create_on:

join_on = car.create_on(car[:engine_id].eq(engine[:id]))
eng_join = car.create_join(engine, join_on, Arel::Nodes::OuterJoin)

Car.joins(eng_join)
Run Code Online (Sandbox Code Playgroud)

要么

使用.join_sources构造的连接对象:

eng_exp = car.join(engine, Arel::Nodes::OuterJoin).on(car[:engine_id].eq(engine[:id]))
Car.joins(eng_exp.join_sources)
Run Code Online (Sandbox Code Playgroud)