title: RubyOnRails multiple scopes composition
body: <p>I got a Product model with has_many Types table and several scopes:</p>
  
  <pre><code>class Product &lt; ActiveRecord::Base
  
    has_many :product_types
    has_many :types, through: :product_types
  
    scope :type1, -&gt; { joins(:types).where(types: { name: "Type1" }) }
    scope :type2, -&gt; { joins(:types).where(types: { name: "Type2" }) }
  
  end
  </code></pre>
  
  <p>When I try to use one scope (Product.type1 for example) all goes well, but two scopes at a time (Product.type1.type2) returns an empty query. Yes, one product may have multiple types.</p>
  
  <p>Final goal is to create a filter of products by type with checkboxes form. When I check type1 and type2 I want to see all my products that have Type1 and Type1 at the same time.</p>
  
  <p><strong>UPD 1</strong></p>
  
  <p>So I've tried to do several queries and then &amp; them as @aaron.v suggested. I wanted to do the logic inside of the function so:</p>
  
  <pre><code>def products_by_type_name(types)
    all_types = types.each { |type| Product.joins(:types).where(types: { name: type }).distinct }
    ...
  end
  </code></pre>
  
  <p>My point was to iterate through each type, collect all products and then &amp; them inside the function.
  The problem is when I'm iterating, each loop returns string instead of array of hashes.</p>
  
  <pre><code>Product.joins(:types).where(types: { name: types }).distinct # returns array of hashes, it's okay.
  
  types.each { |type| Product.joins(:types).where(types: { name: type }).distinct } # each loop returns string (Type name) instead of array of hashes.
  </code></pre>
  
  <p>What am I doing wrong?</p>
  
  <p><strong>SOLUTION 1</strong></p>
  
  <p>Suggested by @aaron.v, explained below</p>
  
  <pre><code>def self.by_type_name(types)
    product_ids = []
    types.each do |t|
      product_ids &lt;&lt; (joins(:types).where(types: { name: t }).distinct.select(:id).map(&amp;:id))
    end
    find(product_ids.inject(:&amp;))
  end
  </code></pre>
  
  <p><strong>SOLUTION 2</strong></p>
  
  <p>Found on reddit.
  In this function you are fetching all products with at least one required type and than grouping only ones that have required count of types. Thus, you get only those products that belongs to every type at the same time.</p>
  
  <pre><code>def self.by_type_name(types)
      joins(:types).where(types: { name: types }).distinct.group('products.id').having('count(*) = ?', types.each.count) 
  end
  </code></pre>