Assume you have these association:
- a user has many likes
- a like is associated to either article or comment
Therefore, a Like model look like this:
class Like < ActiveRecord::Base belongs_to :user belongs_to :likable, polymorphic: true end
Article and comment are all likable.
You can search content of article belonging to a given user like this:
Article.joins(likables: :user).where("users.id = ?", current_user.id)
What if you want to search both article and comment at the same time ? The key is LEFT JOIN.
You need to chain Like, Article and Comment together, then you can search on article and comment at the same time.
To chain them together, try this:
likes = Like.joins("LEFT OUTER JOIN articles on likes.likable_id = articles.id AND likes.likable_type = \'Article\'").joins("LEFT OUTER JOIN comments on likes.likable_id = comments.id AND likes.likable_type = \'Comment\'")
Now, both articles and comments are included, you can search easy:
likes.where("articles.title = ? OR comments.title = ?", "title", "title")
It works in ActiveRecord Relation and can be chained easily. For example, you can even eager-load likable
likes.where("articles.title = ? OR comments.title = ?", "title", "title").includes(:likable)
Then iterate likes to get all matched articles and comments.