Reputation: 2900
I've got three models with below fields (each field after #):
class User < ApplicationRecord
has_many :user_tags, dependent: :destroy
end
class UserTag < ApplicationRecord
belongs_to :user
end
class JourneyTag < ApplicationRecord
belongs_to :journey
end
I want to find all Journeys with tags corresponding to the user's tags - user.user_tags
. How to fetch such data?
What I was trying to do:
current_user.user_tags.each do |user_tag|
JourneyTag.where(cms_tag_id: user_tag.cms_tag_id)
end
Which should gives me JourneyTag with the same cms_tag_id
as user.user_tags
has and then I want to grab this collection of JourneyTag
to find Journey. But above query is unuseful because it always returns some JourneyTag even if it's not matched with user_tag.cms_tag_id
Upvotes: 3
Views: 225
Reputation: 13014
Try:
Journey.joins(:journey_tags).where(journey_tags: { cms_tag_id: current_user.user_tags.pluck(:cms_tag_id) })
Breaking it down:
current_user.user_tags #=> returns all user tag ids associated
current_user.user_tags.pluck(:cms_tag_id) #=> gives all associated cms_tag_id in single SELECT `cms_tag_id` query
journey_tags: { cms_tag_id: current_user.user_tags.select(:cms_tag_id) } #=> executes matching WHERE against JourneyTags
Journey.joins(:journey_tags) #=> filtered JourneyTags joins with Journey
Alternatively, you can try below with manual joins as:
Journey.joins(:journey_tags).joins('INNER JOIN user_tags on user_tags.cms_tag_id = journey_tags.cms_tag_id INNER JOIN users on user_tags.user_id = users.id')
Upvotes: 2