在Rails中编写"(x AND y)OR(a AND b)"where查询的最佳方法是什么?
我刚刚编写了以下消息方法,用于在两个用户之间返回消息。选择是在两个用户之间获取消息,即从我向他们发送消息和他们向我发送消息。
它有效,但看起来很可怕。有没有更简单/更好的写法?
class Conversation
def initialize(me, them)
@me = me
@them = them
end
def messages
t = Message.arel_table
results = Message.where(
(t[:sender_id].eq(@me.id).and(t[:recipient_id].eq(@them.id))).or(
t[:sender_id].eq(@them.id).and(t[:recipient_id].eq(@me.id)))
)
end
end
注意:多亏了Jimmy,我最终得到了:
class Conversation
def initialize(me, them)
@me = me
@them = them
end
def messages
me_to_them = "sender_id = :my_id AND recipient_id = :their_id"
them_to_me = "sender_id = :their_id AND recipient_id = :my_id"
Message.where(
"#{me_to_them} OR #{them_to_me}",
{:my_id => @me.id, :their_id => @them.id}
)
end
end
您可以使用SQL字符串和用于值插值的数组语法对其进行一些清理:
class Conversation < ActiveRecord::Base
def initialize(me, them)
@me = me
@them = them
end
def messages
Message.where(["(sender_id = ? AND recipient_id = ?) OR (sender_id = ? AND recipient_id = ?)", @me.id, @them.id, @them.id, @me.id])
end
end
我以前已经构建了一个类似的系统。然而,我的数据库结构有点不同,以使查询更简单,并允许小组对话(超过2人)
private_message_groups
id | subject
private_message
id | group_id | private_message_group_id | user_id | message
private_message_follow
group_id | user_id | visible
通过这种方式,您可以简单地将用户指向private_message控制器。如果你想让我更深入,我可以,但这个系统的最大优势是现在你有了一个论坛系统。
我也遇到了同样的问题。我在网上搜索了几个小时,终于在Arel::FactoryMethods中找到了一个名为grouping的方法,它只需在表达式周围添加括号。
有了这个,你的方法应该是这样的:
def messages
t = Message.arel_table
results = Message.where(
t.grouping(t[:sender_id].eq(@me.id).and(t[:recipient_id].eq(@them.id))).or(
t.grouping(t[:sender_id].eq(@them.id).and(t[:recipient_id].eq(@me.id))))
)
end