How do you generically call a scope on a model?

18 views
Skip to first unread message

Walter Lee Davis

unread,
Mar 17, 2019, 3:56:05 PM3/17/19
to rubyonra...@googlegroups.com
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
end

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
end

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

Am I wrong about send?

Thanks in advance,

Walter

Eric Anderson

unread,
Mar 18, 2019, 10:29:25 AM3/18/19
to Ruby on Rails: Talk
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.

Eric
Reply all
Reply to author
Forward
0 new messages