As you probably know ActiveRecord allows arrays as arguments of conditions. I remember this feature at least since Rails 2…
So if you write:
Product.where tag_code: [1,2,3]
It produces:
SELECT * FROM products WHERE tag_code IN (1,2,3);
It’s ok, but it’s not a wonderful solution if you have a lot of arguments. You can even have an error because you’re passing too many arguments.
Then Rails 4 added the .pluck
method, and since then I’m seeing a lot of code like:
Product.where tag_code: Tag.pluck(:code)
But pluck
returns an array, so it executes the query right away. In the end you are doing two queries:
SELECT code FROM tags; # => [1,2,3]
SELECT * FROM products WHERE tag_code IN (1,2,3);
DON’T DO THIS. It’s bad. In this case you want to use .select
:
Product.where tag_code: Tag.select(:code)
.select
returns an ActiveRecord relation object, that can be included in other queries. In fact the above code will produce:
SELECT * FROM products WHERE tag_code IN (SELECT code FROM tags);
Leave a Reply