Filter users with a join table

You can get a count and use having to stipulate that the user must have one or more tags:

tags = ["TOS", "TNG"]
User.joins(:tags)
    .where(tags: { tag: tags })
    .group(:id)
    .having(
      # Arel for "COUNT(tags.*) >= ?"
      Tag.arel_table[Arel.star].count.gte(tags.length)
    )

Since you’re using a polymorpic assocation you probaly want to bake this into a module so that you can reuse it:

module Taggable
  extend ActiveSupport::Concern
  included do
    has_many :taggings, as: :taggable
    has_many :tags, through: :taggings
  end

  class_methods do
    def with_tags(*tags) 
      joins(:tags)
        .where(tags: { tag: tags })
        .group(:id)
        .having(  
          Tag.arel_table[Arel.star]
             .count.gteq(tags.length)
        )
    end
  end
end
class User < ApplicationRecord
  include Taggable
end

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top