is there anyway to combine these into one ActiveRecord query?
I am wondering if there is anyway to combine these two queries without using a string in the where call... ?
Notification.where(:notifiable_type => "Post", :notifiable_id => post.id)
Notification.where(:notifiable_type => "Comment", :notifiable_id => post.comments.map(&:id))
In other words, I 开发者_JAVA百科am looking for a way to accomplish this without doing:
Notification.where("(notifiable_type = 'Post' AND notifiable_id = ?) OR (notifiable_type = 'Comment' AND notifiable_id in (?))", [post.id, post.comments.map(&:id)])
Is it possible?
You can use MetaWhere to achieve what you are looking for in a clean and readable way:
Notification.where(
(:notifiable_type => "Post" & :notifiable_id => post.id)
|
(:notifiable_type => "Comment" & :notifiable_id => [post.comments.map(&:id))
)
I'm sure this could be cleaned up/refactored, but something like this could do the trick.
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
The problem is that (last I checked) there's no way to chain OR conditions with ActiveRecord's implementation of Arel. Furthermore you can't |
scopes (but you can &
them).
There are gems that people have written that will allow you do write more expressive ActiveRecord queries. Metawhere is the first that comes to mind.
精彩评论