3
\$\begingroup\$

I have a RoR 4 app, and its model have these associations:

has_many :accreditations
has_one :legal, -> { where(kind_cd: Accreditation.legal) }, class_name: 'Accreditation'
has_many :departments, -> { where(kind_cd: Accreditation.department) }, class_name: 'Accreditation'

So, you see that these associations similar, but legal & departments have more conditions than accreditations. Can I replace class_name: 'Accreditation' with something like using :accreditations?

\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

I don't see what you will gain with your hypothetical using syntax, let's say there is one... your code will look like this:

has_many :accreditations
has_one :legal, -> { where(kind_cd: Accreditation.legal) }, using: :accreditations
has_many :departments, -> { where(kind_cd: Accreditation.department) }, using: :accreditations

How is it better than your current code? It is not more expressive, nor is it more succinct, nor DRY.

Also, these associations are similar to some extent, but they look as DRY as you can make them - one is has_one, while the others are has_many, one uses the default idiom, while the others have names different than the associated class, conditions are different (and though one might argue you can predict the filter by the association name, one is singular, and the other is plural...)

In short, I think your current code is good enough - any change will only harm readability.

\$\endgroup\$
1
  • \$\begingroup\$ Uri, but if I make two queries like @accreditations = @contractor.accreditations;@legal = @contractor.accreditations I'll get second query faster because it will use cache from first query, isn't it? \$\endgroup\$ Commented Mar 27, 2014 at 5:31
4
\$\begingroup\$

There are two ways to tackle this situation. One of them is what you did: follow the Law of Demeter; I don't have any advice to improve your code. The second way is move the logic to the other model. In that case you'd write:

class Company
  has_many :accreditations
end

class Accreditation
  scope :departments, where(kind_cd: department)

  def self.legal
    where(kind_cd: legal).first
  end
end

Both are ok even though I prefer the second because the logic of departments/legal is within the accreditation model.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.