开发者

is there anyway to combine these into one ActiveRecord query?

开发者 https://www.devze.com 2023-04-01 04:53 出处:网络
I am wondering if there is anyway to combine these two queries without using a string in the where call... ?

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消