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) }

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.

Image source: pexels.com

Download free RSpec & TDD ebook

Do you want to earn more or jump to the next level in your company? Do you know that testing skills are one of the most desired skills? There is only first step: start testing and do it right. My ebook can help you. Subscribe to the newsletter to get a free copy of the book.

3 Comments

  1. Pingback: 週刊Railsウォッチ(20180112)update_attributeが修正、ぼっち演算子`&.`は`Object#try`より高速、今年のRubyカンファレンス情報ほか

  2. Pingback: Rails: モデルのクエリをカプセル化する2つの方法(翻訳)

  3. Published the JP translation https://techracho.bpsinc.jp/hachi8833/2018_01_16/51052
    Thank you very much for your kindness!

Leave a Comment

Your email address will not be published. Required fields are marked *