0

I have user model with :except_ids scope:

scope :except_ids, ->(*ids) { where { id.not_in ids } }

The problem is - I can't use it with another lazy queries. For example, if I call something like this:

User.except_ids(User.except_ids(1,2))

I end up with

TypeError: Cannot visit Arel::SelectManager

I have much more complex query in my project, but everything works fine - except that scope. I can make it work by replacing scope by actual code, but that smells.

So, is there any way to find this out?

ekremkaraca
  • 1,453
  • 2
  • 18
  • 37

1 Answers1

2

If you want to achieve this with a single SQL query, it has to contain a subquery, which is not directly supported by Arel, but you can use this workaround, for example.

The error you see is probably caused by the fact, that User.except_ids(1,2) returns an instance of ActiveRecord::Relation, which may be a problem for the splat operator in the signature of the lambda. This works, but results in 2 queries:

User.except_ids(User.except_ids(1,2).map(&:id))
Community
  • 1
  • 1
mxgrn
  • 1,733
  • 16
  • 20
  • Well, the thing is, map(&:id) will load results for relation inside brackets. The point of all my manipulations is to generate one giant query. –  Apr 02 '13 at 09:57
  • 1
    For greater efficiency with the double-query solution, use pluck rather than map: `User.except_ids(User.except_ids(1,2).pluck('id'))`. This produces a `SELECT id` rather than a `SELECT *`, and returns it in an array with only the ids. – zykadelic Jan 10 '14 at 11:28