Now and then I get question from people should they use class method or the scope DSL for ActiveRecord scope. At first I thought they are the same but in fact there are minor differences.
How to define scope?
There are 2 ways to define ActiveRecord model scope:
- scope DSL
- class method
Let’s see both of them in action with following example:
1 2 3 4 5 6 7 8 9 10 11 12
Both ways returns us ActiveRelation scope which seems the same. In fact in this case, they are alike with one minor difference, that is the DSL version doc comment won’t be picked up by RDoc.
Please be careful if you have a complex scope like below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
As you can see above, the scope involves condition check and in the DSL
return if it is night shift. You might be wondering what object
is returned implicitly. For the DSL version, the chain scope is returend,
that is the ActiveRelation object.
I naively copy 1:1 the same implementation of DSL to my class method implementation
and I got
nil as returned value instead. This breaks the chain (if we use our scope in combination
with other scopes). The class method must be rewritten as:
1 2 3 4 5 6 7
Please be noted that I returned a
scoped which is an anonymous scope. This object
is a ActiveRelation object and would keep the chain intact.
What would you use? I myself prefer class method for I find sugar syntax of Rails (which is nice) does not add in much value. Yet having said so, I do use DSL from time to time if the scope is tiny.