ruby-on-railspostfindmany-to-manyacts-as-taggable

Rails finding all posts with certain tags without using acts_as_taggable


So I'm trying to learn rails and I don't want to cheat just yet.

post model:

class Post < ActiveRecord::Base
    has_many :features
    has_many :tags, :through => :features
end

tag model:

class Tag < ActiveRecord::Base
    has_many :features
    has_many :posts, :through => :features
end

join table:

class Feature < ActiveRecord::Base
    belongs_to :tag
    belongs_to :post
end

I already know how to associate posts with tags by doing: Post.find_by_id(1) << Tag.first

Now, I'm stuck on searching for posts with certain tags. How do I search for all posts that have one or more of the following tags: "swimming", "running", "making money".

Post1 includes tags: "biking", "rock climbing", "swimming"

Post2 includes tags: "frogs", "fish"

Post3 includes tags: "making money", "swimming", "biking", "love"

Post4 includes tags: "swimming"

I want the posts that matches the user's interests the most to show up first.

example: user should see a list of posts in this order.... post3, post1, post4. If this is too hard, a method of finding all posts with the exact tags will suffice I guess.


Solution

  • You should just be able to do

    @tag.posts
    

    Is there any reason you didn't use the has_and_belongs_to_many relation?

    UPDATE:

    Per your comment:

    tag_ids = [1, 2, 3] # aka the IDs for tags ["swimming", "running", "making money"]
    matches = {}
    @posts.each do |post|
      count = 0;
      post.tags.each do |tag|
        count += 1 if tag_ids.include? tag.id
      end
      matches[count] ||= []
      matches[count] << post
    end
    

    Could probably be optimized a bit, but matches will then include all the posts matching the requested tag in keys according to the number of matches. This should also probably go in a class method for the Posts model instead of in the controller.