我想知道是否还有将这两个查询在没有的情况下使用where调用中的字符串进行组合...?
Notification.where(:notifiable_type => "Post", :notifiable_id => post.id)
Notification.where(:notifiable_type => "Comment", :notifiable_id => post.comments.map(&:id))
换句话说,我正在寻找一种方法来实现这一点而不做:
Notification.where("(notifiable_type = 'Post' AND notifiable_id = ?) OR (notifiable_type = 'Comment' AND notifiable_id in (?))", [post.id, post.comments.map(&:id)])
有可能吗?
答案 0 :(得分:3)
您可以使用MetaWhere以清晰易读的方式实现您的目标:
Notification.where(
(:notifiable_type => "Post" & :notifiable_id => post.id)
|
(:notifiable_type => "Comment" & :notifiable_id => [post.comments.map(&:id))
)
答案 1 :(得分:0)
我确信这可以清理/重构,但这样的事情可以解决问题。
class Notification
scope :on_post_or_its_comments, lambda {|post|
on_post = arel_table[:notifiable_type].eq('Post').
and(arel_table[:notifiable_id].eq(post.id))
posts_comments = arel_table[:notifiable_type].eq('Comment').
and(arel_table[:notifiable_id].in(post.comments.map(&:id))
where on_post.or(posts_comments)
}
end
问题是(最后我检查过)没有办法用ActiveRecord的Arel实现链接OR条件。此外,你不能|
范围(但你可以&
)。
人们编写的宝石可以让你写出更具表现力的ActiveRecord查询。首先想到的是Metawhere。