Within Ruby on Rails (or any other language with a collection...) is it necessary to break Law of Demeter violations up when querying something simple like a count?
class Survey
has_one :kingdom
def first_survey?
# Should this be broken according to Law of Demeter?
self.kingdom.surveys.count == 1
# -or-
self.kingdom.surveys_count == 1
end
end
class Kingdom
has_many :surveys
# Is this the "right thing to do", or overkill?
def surveys_count
self.surveys.count
end
end
Usually when I see Law of Demeter violations the first question I ask isn't "How do I 'avoid a dot'?" The question you should ask is "Does this functionality that violates belong to someone else?" In this case I would probably structure it like so:
class Survey
belongs_to :kingdom
end
class Kingdom
has_many :surveys
def first_survey?(survey)
surveys.first == survey
end
end
kingdom = Kingdom.find(kingdom_id)
first_survey = kingdom.surveys.first
last_survey = kingdom.surveys.last # Assuming there is more than one survey.
kingdom.first_survey?(first_survey) #=> true
kingdom.first_survey?(last_survey) #=> false
By structuring it this way the Survey
no longer has to reach into the Kingdom
object and query its assocations, avoiding the Law of Demeter violation. This also allows you to change the definition of first_survey?
later on. A contrived example would be if Surveys
could be "published". The first_survey?
for a Kingdom
could then be easily changed to support only checking if the passed in Survey
is the first Survey
with the published
attribute set to true
.