How do you generically call a scope on a model?

I want to (in a metaprogramming context) invoke a scope on an ActiveRecord based model. I know the name of the scope, but I don't want to use `send` to do this, because send can be evil. I know that ActiveRecord defines a class method named scope that gathers up these scopes somewhere internally, but I can't figure out where that is, or how you can pick one out of the stack to execute.

What is the best equivalent to this (completely made-up example):

def call_scope(model, scope = 'all')
  model.send scope.to_sym

The key feature is that we late-evaluate which model and which scope, so it can be used inside an enumerator, and doesn't rely on knowing the exact parties in play.

Would this be a good place for class_eval? (I just tried that, and it works)

def call_scope(model, scope = 'all')
  model.class_eval scope.to_s

Is there something more Rails-like I could/should use?

Am I wrong about send?

Thanks in advance,


I don’t have the answer to your question, but I wouldn’t say send is inherently evil. It all depends on the source of the data. If your scope argument is some meta-programming (i.e. the value is defined by the programmer) then it can be safe to use. If it is user input then obviously you would want to whitelist against the scopes you have defined.

Also remember scopes are just a class method that returns an ActiveRecord::Relation. I.E. you may have a “scope” that wouldn’t be on any Rails internal data structure if the scope method was not used to define it.