Reputation: 2343
Let's say I got questions that have multiple tags on them. I want to be able to find related questions by tags (similar to e.g. iTunes Genius) or find related tags for a tag based on the questions that share them.
Unfortunately, I have no clue how to do that. Especially when it comes to related tags.
I hope somebody can give me a hint! Thanks a lot!
Upvotes: 2
Views: 215
Reputation: 35533
Accomplishing this efficiently requires a strong understanding of SQL. You can use ActiveRecord to help you build the queries, but the strategy actually lies in the SQL query that will be generated.
Assuming you have Tag and Question models with a QuestionTag
join model for a has-many-through
relationship:
class Question < ActiveRecord::Base
has_many :question_tags
has_many :tags, :through => :question_tags
end
class Tag < ActiveRecord::Base
has_many :question_tags
has_many :questions, :through => :question_tags
end
class QuestionTag < ActiveRecord::Base
belongs_to :question
belongs_to :tag
end
You can do this to find questions matching a particular tag:
tag = Tag.find_by(name: 'foo')
related_questions = tag.questions
And you can also find questions that match all of a set of tags:
tag_names = ['foo', 'bar', 'baz']
subquery = QuestionTag.joins(:tag).
select('question_tags.question_id').
where(tags: {name: tag_names}).
group('question_tags.question_id').
having("COUNT(*) = #{tag_names.size}").to_sql
related_questions = Question.where("id IN (#{subquery})")
You can find tags related to a specific tag like this:
tag = Tag.find_by(name: 'foo')
subquery = tag.question_tags.select('question_tags.question_id').to_sql
related_tags = Tag.joins(:question_tags).
where("question_tags.question_id IN #{subquery}").
where.not(id: tag.id)
Upvotes: 3
Reputation: 76
What you're describing is a many-to-many relationship meaning that questions can have many tags and tags many questions. To do this you must create a third table the consists of tag_ids and question_ids to do this you will need to read up on active record associations. Specifically the has-many-through association. http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association I am currently taking a web development class and we went over this yesterday with students and classes here are our notes. Which walks through creating the models and using them I suspect it would be really helpful for you. https://github.com/wdi-sf-jan-2014/notes/blob/master/active_record_associations/migrations_and_associations.md
Upvotes: 1