2

I have two models in my rails 5 application:

class Post < ApplicationRecord
  has_many :tags
end

class Tag < ApplicationRecord
  belongs_to :post
end

In my data base I have for example two post with 2 different tags each. How can I search my post by two specifics tags (tag.title="tagname1" AND tag.title="tagname2"):

Post.includes(:tags).where(tag: {title: "tagName1"}).where(tag: {title: 
"tagName2"})

thanks

3 Answers 3

2

Solution

Post.joins(:tags)
  .where(tags: { title: ['tag1', 'tag2'] })
  .group('posts.id')
  .having('count(tags.post_id) = ?', 2)

Assumptions:

  • you have a uniqueness validation for tag.title for each post like the following:

    class Tag < ApplicationRecord
      belongs_to :post
    
      validates :title, uniqueness: { scope: :post }
    end
    

    ... otherwise, solution above won't work, because:

    # it will still also match the following Post
    Post(id: 1)
      Tag(post_id: 1, title: 'tag1')
      Tag(post_id: 1, title: 'tag1')
    
    # but that you only want instead those like the following:
    Post(id: 2)
      Tag(post_id: 2, title: 'tag1')
      Tag(post_id: 2, title: 'tag2')
    
Sign up to request clarification or add additional context in comments.

Comments

1

You could use arel for cleaner queries.

Post.joins(:tags).where(Tag.arel_table[:title].in(['tagName1', 'tagName']))

3 Comments

You will get posts with both, as it will do OR operation when you use it like this. This is just SQL IN statement
hmm I wonder if the OP wants to get Posts having both tags, and therefore not OR
sorry @Nermin , I mean that I need get the post with "tagName1" tag AND "tagNam" tag, no OR
0

search post by two specifics tags

Post.includes(:tags).where("tags.title IN (?)",["tagName1", "tagName"]).references(:tag)

This will return all posts having tags.title either "tagName1" or "tagName"

3 Comments

@jorgeregidor Exactly you'll get the same.
sorry @Gabbar , I mean that I need get the post with "tagName1" tag AND "tagNam" tag, no OR
@jorgeregidor Post.includes(:tags).where("tags.title = ? AND ?","tagName1", "tagName").references(:tag) Probably this is what you want. ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.