问题
I have a product that has many variants, those variants have two attributes: Size and Color.
I want to query for the Variant based on the two attributes I pass in - I got it to work with following:
variants = Spree::Variant.joins(:option_values).where(:spree_option_values => {:id => size.id}, :product_id => prod.id).joins(:option_values)
variant = variants.select{|v| v.option_values.include?(size)}
From my understanding, the select method more or less iterates through the array, which is kinda slow. I would rather have a query that finds the variant directly based on those two attributes.
I tried the following:
Spree::Variant.joins(:option_values).where(:spree_option_values => {:id => size.id}, :product_id => prod.id).joins(:option_values).where(:spree_option_values => {:id => color.id})
but this only ended up in returning an empty array.
How would I go about this?
Edit: Here are the product, variant and option_values models:
Product: https://github.com/spree/spree/blob/master/core/app/models/spree/product.rb
Variant: https://github.com/spree/spree/blob/master/core/app/models/spree/variant.rb
OptionValue: https://github.com/spree/spree/blob/master/core/app/models/spree/option_value.rb OptionType: https://github.com/spree/spree/blob/master/core/app/models/spree/option_type.rb
回答1:
Updated 2: you're right, this is not what you looking for.
So you can:
1) Build SQL subquery: (if joined table has size and has color at the same time then return TRUE). How quick it will be working - is a question...
2) Imagine you've created a model "ValuesVariants" for table "spree_option_values_variants" and kicked out habtm (replace with 2 has_manys + 2 has_manys through). Now you can search ValuesVariants with (option_type_id = size_id||color_id AND variant_id IN (array of product's variant ids)), extracting matched variants. It can be quick enough...
3) You can use :includes. so associated objects loaded into the memory and the second search do by array methods. In this case the concern is in memory usage.
来源:https://stackoverflow.com/questions/13996736/querying-based-on-two-associated-records