class RailsBestPractices::Reviews::LawOfDemeterReview
Review
to make sure not to avoid the law of demeter.
See the best practice details here rails-bestpractices.com/posts/2010/07/24/the-law-of-demeter/
Implementation:
Review
process:
check all method calls to see if there is method call to the association object. if there is a call node whose receiver is an object of model (compare by name), and whose message is an association of that model (also compare by name), and outer the call node, it is also a call node, then it violate the law of demeter.
Constants
- ASSOCIATION_METHODS
Private Instance Methods
is_association_attribute?(association_class, association_name, attribute_name)
click to toggle source
# File lib/rails_best_practices/reviews/law_of_demeter_review.rb, line 54 def is_association_attribute?(association_class, association_name, attribute_name) if association_name =~ /able$/ models.each do |class_name| if model_associations.is_association?(class_name, association_name.sub(/able$/, '')) || model_associations.is_association?(class_name, association_name.sub(/able$/, 's')) return true if model_attributes.is_attribute?(class_name, attribute_name) end end else model_attributes.is_attribute?(association_class, attribute_name) end end
need_delegate?(node)
click to toggle source
check if the call node can use delegate to avoid violating law of demeter.
if the receiver of receiver of the call node matchs any in model names, and the message of receiver of the call node matchs any in association names, then it needs delegate.
# File lib/rails_best_practices/reviews/law_of_demeter_review.rb, line 43 def need_delegate?(node) return unless variable(node) class_name = variable(node).to_s.sub('@', '').classify association_name = node.receiver.message.to_s association = model_associations.get_association(class_name, association_name) attribute_name = node.message.to_s association && ASSOCIATION_METHODS.include?(association['meta']) && is_association_attribute?(association['class_name'], association_name, attribute_name) end