简体   繁体   中英

Rails quickly find record where has_many associations exactly match array of association ids

I've got a Product model which has_many OptionValue records, which describe color , size , etc.

Within my code, I need to query the Product model where the product.option_values.pluck(:id) array exactly matches an array of (eg) options = [1, 6, 4] .

Running something like Product.includes(:option_values).where(option_values: { id: options_array }) returns all values that match at least one element of the options array, rather than all of them.

I've developed an inefficient way of getting the record I need, as follows:

Product.all.each { |v| return v if v.option_values.pluck(:id).sort == options_array.sort }

Obviously the above is way ott and I'm sure there's a simpler way to handle this, and I'm happy to use ActiveRecord or a straight SQL query (though I'm not too hot on the latter, so haven't come up with anything yet).

Any advice on the best way of achieving this greatly appreciated. Not sure I've explained this perfectly, so please comment if you've any questions.

Thanks in advance, Steve.

Clocked this in my old questions and threw together a quick and easy solution, so dropping it here for anyone else that might come this way:

product_options = product.option_values.pluck(:id)
unless options_array.length < product_options.length
  (product_options & options_array).length == product_options.length
end

This:

  • checks the options_array is long enough to contain the necessary matches
  • looks for the elements in common across the two arrays ( (product_options & options_array) )
  • measures their length
  • checks this is the same length as the desired array product_options , meaning all the required options were found.

Alternatively, you can subtract one from the other and check there's nothing leftover (ie missing):

(product_options - options_array).empty?

Hope this helps someone at some point.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM