Quassnoi опубликовал запрос MySQL, который делает то, что вы хотите. Вот метод для модели Variant
, который сделает эквивалент. Я делаю два подхода, один, если variant_attributes (variant_id, id)
уникальная комбинация, и один, если они не
Unique:
class Variant < ActiveRecord::Base
has_many :variant_attributes
named_scope :with_variant_attributes, lamda { |*ids|
ids = ids.flatten
if(ids.length>0)
result = {:include => :variant_attributes}
sql_params = {:length => ids.length,:ids => ids}
result[:conditions] = ["(:length = (select count(*) from variant_attributes
where id in (:ids))",sql_params]
result
else
nil
end
}
end
Не уникален
class Variant < ActiveRecord::Base
has_many :variant_attributes
named_scope :with_variant_attributes, lamda { |*ids|
ids = ids.flatten
if(ids.length>0)
result = {:include => :variant_attributes}
conditions = []
sql_params = {}
ids.each_with_index do |id,i|
conditions << "( 1 = Select Count(*) from variant_attributes where id = :id#{i})"
sql_params["id#{i}"] = id
end
result[:conditions] = [ '(' + conditions.join(' AND ') + ')', sql_params]
result
else
nil
end
}
end
Который может использоваться следующими способами:
# Returns all Variants with variant_attributes 1, 2, & 3
vars = Variant.with_variant_attributes(1,2,3)
# Returns Variant 5 if it has attributes 3 & 5, or null if it doesn't
vars = Variant.with_variant_attributes(3,5).find_by_id(5)
#Returns Variants between 1 and 20 if that have an attribute of 2
vars = Variant.with_variant_attributes(2).find(:conditions => "id between 1 and 20")
#can accept a variable array of ids
my_ids = [3,5]
vars = Variant.with_variant_attributes(my_ids)
Этот код не был проверен.