That is the quick one: there is no doubt that it’s better to isolate database query logic from other classes such as services or controllers. If you want to put it in a model you can consider these two options:

Class method

def self.recent
  order(created_at: :desc)
end

ActiveRecord scope API

scope :recent, -> { order(created_at: :desc) }

Want to receive useful tips, information about new Ruby gems and articles on a daily basis? Make sure you follow me and say hello!

Which one?

You may say it’s just a matter of taste because Active Record will convert a scope into a class method anyway but:

Scopes are always chainable

Even if you use condition inside the definition, like this:

scope :by_email, -> |email| { where(email: email) if email.present? }

having the same with class method would not allow you to chain methods

def self.by_email(email)
  where(email: email) if email.present?
end

because self.by_email would return nil when email would be blank

So which one?

Pick up the one that your team like the most and try to stick to selected convention across the whole app.

Want to become a better Rails developer?
Download for free the Introduction Rails patterns book and dive into the world of refactoring and easy-testable Ruby code today.
Join over 1,000 developers already subscribed to my newsletter and download the book. You can unsubscribe anytime:

Subscribe and get the book!