Rails-如何使用Arel左联接,包括默认范围条件

时间:2018-08-12 11:24:14

标签: ruby-on-rails ruby arel

我有一个项目正在使用旧版本的Rails 4.1.X,目前我们无法轻松将其升级到5.X4.2(但是从长远来看,我们会做这个)。

我们正在使用一些附加default_scope的宝石(我知道default_scope是邪恶的:>),例如

paranoia-> WHERE deleted_at IS NOT NULL

我想收到这样的SQL查询:

SELECT tablea.*
FROM tablea
LEFT OUTER JOIN tableb ON tablea.fkey = tableb.id AND tableb.deleted_at IS NULL
WHERE table1.deleted_at IS NOT NULL AND
-- other conditions
[...]

我知道用LEFT JOIN编写Rails 4.X的2种方法,但是每种方法都有缺点:

1)例如。

activity = Activity.arel_table
activity_join_on = activity[:person_id].eq(person[:id])
  .and(activity[:deleted_at].eq(nil))
activity_join = Arel::Nodes::OuterJoin.new(activity, Arel::Nodes::On.new(activity_join_on))
Person.joins(activity_join)

这种方法的问题是我们必须手动编写样板 deleted_at IS NULL和其他内容。一次或两次编写就可以了,但是我宁愿避免使用它,不要“弄乱”代码库。

2)eager_load

Tablea.eager_load(:tableb)

这更方便,但是我们从tableatableb中进行选择,而我并不一定总是这样做。此外,如果我有自定义的SQL选择,则将无法使用。

Rails 4.X)中我想实现的目标类似于RoR 5.0+方法:

Tablea.left_outer_joins(:tableb)
# this will automatically pickup deleted_at conditions

借助一些宝石(可以)或通过原始RoR / Ruby(首选)。

0 个答案:

没有答案