Arel:使用符号进行左外连接

5
我有一个使用案例,其中我从某个模型获取符号化的深度关联,并且必须执行涉及使用外连接的某些查询。如何在不手动编写完整SQL的情况下完成这项任务?
我不想要的答案: - 使用includes(不能很好地解决深度关联问题(.includes(:cars => [:windows, :engine => [:ignition].....表现出意外行为),而且我不想要它的副作用) - 自己编写SQL(抱歉,现在是2013年,需要跨数据库支持等等,而且我获取的对象是只读的,会产生更多的副作用)
我想要一个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!!

我不知道为什么这个方法不起作用。我也不确定到底缺少什么。但现在它是离解决问题最近的方法了。如果有人能够帮助我完善我的示例,或者提供一个好的解决方案,或者告诉我Rails何时将包含如此明显必要的功能,我将永远感激。

3个回答

9

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

如果您想要一个可以传递到.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)

或者

使用您构建的联接对象中的.join_sources:

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

7

这是我们能得到的最接近答案了,恐怕我唯一的问题就是对于关联键的先前知识(我希望有一个更开箱即用的解决方案,比如普通的 AR 内连接)。但这绝对是对这个问题最好的答案,我已经根据它设计出了一个解决方案。再次感谢。 - ChuckE

0

如果您不介意添加依赖并完全跳过AREL,您可以使用Ernie Miller的优秀Squeel gem。它会是这样的

Car.joins{engine.outer}.where(...)

这将需要将汽车模型与引擎相关联,如下所示:

belongs_to :engine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接