Skip to content

Instantly share code, notes, and snippets.

@sbeam
Created October 16, 2012 17:48
Show Gist options
  • Save sbeam/3900837 to your computer and use it in GitHub Desktop.
Save sbeam/3900837 to your computer and use it in GitHub Desktop.
Spree::Variant.find_by_options
Spree::Variant.class_eval do
# find variants matching the given map of option_type.id's to option_value.id's
# and optionally limited to one product
# Spree::Variant.find_by_options {'4'=>'14','1'=>'3',2=>6, 3=>10}, product
def self.find_by_options opts={}, product=nil
sovv = Arel::Table.new :spree_option_values_variants
sot = Spree::OptionType.arel_table
sov = Spree::OptionValue.arel_table
variant = self.arel_table
relation = variant.project(Arel.sql(self.table_name+'.*'))
opts.each_with_index do |(option_type_id, option_value_id), i|
sovv_a = sovv.alias "sovv_#{i}"
sot_a = sot.alias "sot_#{i}"
sov_a = sov.alias "sov_#{i}"
relation = relation.join(sovv_a).on( sovv_a[:variant_id].eq(variant[:id]) ).
join(sov_a).on( sov_a[:id].eq(sovv_a[:option_value_id]) ).
join(sot_a).on( sot_a[:id].eq(sov_a[:option_type_id]) ).
where( sot_a[:id].eq(option_type_id) ).
where( sov_a[:id].eq(option_value_id) )
end
if product && product.respond_to?(:id)
relation = relation.where(variant[:product_id].eq(product.id))
end
self.find_by_sql(relation.to_sql)
end
# v.project(Arel.sql('*')).join(sovv).on(sovv[:variant_id].eq(v[:id])).join(sov2).on(sov[:id].eq(sovv[:option_value_id])).join(sot).on(sot[:id].eq(sov2[:option_type_id])).where(sot[:id].eq(4)).where(sov2[:id].eq(14)).to_sql
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment