Why 'Use def self.method, not the scope :method DSL.'?

I was browsing the style guide when I found this recommendation.

If I remember correctly the advantage of using the scope DSL is that brings always a relation when the result may be empty, in order to chain the results. So I was a little puzzled by this recommendation.

Is there any specifics of why is this recommended?

I believe that those benefits appeared only in Rails 4.0. Before that self.method was the way to go. Nowadays I believe it is not.

@Cicloid I think you remember correctly. scope can chain even insides the block return nil, but that case usually involve conditional logic that’s what we try to avoid in the block anyway. So I totally agree on style guide to use class methods instead.

scope :by_status, -> status { where(status: status) if status.present? }

# should be same in Rails 4

def self.by_status(status)
  if status.present?
    where(status: status) 
  else
    all
  end
end

Check this out: http://blog.plataformatec.com.br/2013/02/active-record-scopes-vs-class-methods/

If you want conditional scopes or more complex stuff, moving it to a method is best, but for simple queries a scope is nice. At least in my opinion.

@zamith totally agree :+1:

I like to have my classes methods (Singleton or Instance) defined in code where it makes sense. I don’t feel like the scope macro saves me much and it does cost me ctag compatibility and can easily hide growing complexity (in sheer number of methods defined). Additionally, there have historically been problems with the behavior of scope as compared to class methods.

1 Like

An additional benefit of an ‘Always use methods’ guideline: You don’t have to think about whether something is too complex for a scope macro. It’s one more decision removed.

1 Like