AREL中的分组和分组

bra*_*rad 9 ruby sql arel

我正在尝试使用arel查询此sql代码段的等效内容:

WHERE (("participants"."accepted" = 'f' AND "participants"."contact_id" = 1) 
  OR "participants"."id" IS NULL)
Run Code Online (Sandbox Code Playgroud)

所以我想要 (accepted && contact_id=1) OR NULL

这是我在AREL中得到的

participants[:accepted].eq(false).and(participants[:contact_id].eq(1).
  or(participants[:id].is(nil)
Run Code Online (Sandbox Code Playgroud)

问题是,这会产生:

("participants"."accepted" = 'f' AND "participants"."contact_id" = 1 OR "participants"."id" IS NULL)
Run Code Online (Sandbox Code Playgroud)

请注意我和条件周围缺少括号.我相信根据运营商的优先顺序,我得到了:

accepted && (contact_id=1 OR NULL)
Run Code Online (Sandbox Code Playgroud)

在AREL查询中添加括号没有任何影响.有什么想法吗?

Bri*_*ahn 25

您可以使用生成括号Arel::Nodes::Grouping.

participants = Arel::Table.new("participants")

arel = participants.grouping(
  participants[:accepted].eq(false).and(participants[:contact_id].eq(1))
).or(participants[:id].eq(nil))

arel.to_sql # => (("participants"."accepted" = 'f' AND "participants"."contact_id" = 1) OR "participants"."id" IS NULL)
Run Code Online (Sandbox Code Playgroud)


tok*_*and 7

我相信根据运营商的优先顺序

问题是AND的优先级高于OR.所以1 AND 2 OR 3相当于(1 AND 2) OR 3.作为旁注:如果你使用像这样的包装器,你可以使用Arel编写更好看的代码:

User.where((User[:created_at] > 3.days.ago) & (User[:enabled] == true))
Run Code Online (Sandbox Code Playgroud)