1

Let's say I have two models

class Client < ActiveRecord::Base
  has_many :accounts
end

class Account < ActiveRecord::Base
  belongs_to :client
end

Now, I want to have convenient method to access approved accounts(:approved => true). What is better to use, and why?

  1. has_many: approved_accounts, -> { where :approved => true } for Client model
    or
  2. scope: approved, -> { where :approved => true } for Account model
bbbonthemoon
  • 1,760
  • 3
  • 19
  • 31

2 Answers2

2

Short answer, It Depends. For Long answer, kindly read on...

  • Conditional associations allows us to Customize the query that ActiveRecord will use to fetch the association. Use when you are sure that this condition is permanent & you will never-ever need access to data that doesn't fit the conditional(atleast not in this model) as Conditional associations are APPLIED to every query to ActiveRecord does to the association from that particular model.

  • Scope It is basically, a class method for retrieving and querying objects. so what you are actually doing is defining the following method in your model.

    class Client < ActiveRecord::Base self.approved where(:approved => true) end end

so scope is generally use to define short names for one or more regularly used query customization. But important difference is that scope is not auto-applied unless you use default_scope but conditional associations are auto-applied.

In your case, you want to show unapproved accounts in this model? If not, then use conditional association. Else use scope

CuriousMind
  • 33,537
  • 28
  • 98
  • 137
1

According to me, the scope solution seems the better:

As you probably know, to get the approved accounts of a client, you can do: approved_accounts = client.accounts.approved which is not less legible than: approved_accounts = client.approved_accounts

So not many difference here. But if in the future you want the list of all approved accounts (for statistics or whatever), with the scope solution, a single approved_accounts = Account.approved will be enough. But if you choose the client side, it will be trickier to get (understand: you will have to use the Client model).

Just consider than being approved is a property of an Account more than a property of a Client and it should be clearer that the scope is the best solution.

Hope this clarifies things.

mdemolin
  • 2,514
  • 1
  • 20
  • 23