Search code examples
ruby-on-railsrubylaw-of-demeter

Does the law of Demeter also apply to standard ActiveRecord object methods?


Say you have a class, Car, which has a Driver. If you wanted to access the driver's age, you would do:

@car.driver_age

Instead of

@car.driver.age

If you have delegated the driver's age attribute in the Car model (with prefix set to true).

However, if you also had a Passenger class and you wanted to access the number of passengers in the car, is the following not breaking the Law of Demeter, or is my thinking over-zealous:

@car.passengers.count

Solution

  • I think that count is so general that i would not find it necessary to proxy the call. I would ask myself the question:

    Is it possible that there will be an implementation of passengers in the future, that will not respond to count?

    Since passengers is extremely likely to be a container type forever, and all container types in Ruby (Array, Hash, …) respond to count in the way you would expect, i would answer this question with “no” and therefore stick with @car.passengers.count.

    EDIT

    But if you’re being strict, you are indeed breaking the Law of Demeter. Consider for example a class RobotCar < Car that has no passengers at all. Now, following LoD you could simply return 0 from the method car.passenger_count, whereas when not following LoD you would have to return an empty container from passengers in order not to break other code.

    In the end, you will have to decide for yourself just how likely it is that the interface will ever change. If you are very certain that it won't ever change, then i guess it's ok to disobey LoD.