Module: HasAssociativeFacades::InstanceMethods
- Defined in:
- lib/has_associative_facades/instance_methods.rb
Instance Method Summary collapse
-
#method_missing(method, *args) ⇒ Object
When the method being called is the case of “#association_name_#attribute_or_method” a getter method will be defined and called returning its value.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
When the method being called is the case of “#association_name_#attribute_or_method” a getter method will be defined and called returning its value. This works for an ActiveRecord object created through the new operator having all attributes set to nil or an find of some sort having all attributes populated.
If the associated object is nil but has an attribute or method with the given name a nil is reurned. Otherwise, the NoMethodError is raised.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/has_associative_facades/instance_methods.rb', line 11 def method_missing( method, *args ) method_name = method.to_s super( method, *args ) # allow super to win if it has the method rescue NoMethodError => ex association = nil association_reflection = nil associateds = self.class.inheritable_attributes[:reflections] associateds.each do |associated| if /#{associated[0]}_/.match( method_name ) association_reflection = associated association = associated[0] break end end if association.nil? raise NoMethodError.new('has_associative_facades could find no ' + 'association to resolve ' + "#{self.class.name}##{method}", method, args) end if match = /#{association}_([_a-zA-Z]\w*)/.match( method_name ) if match.captures.empty? || match.captures.size > 2 raise NoMethodError.new('has_associative_facades failed to resolve ' + "#{self.class.name}##{method} via " + "#{self.class.name}##{association}", method, args) end attribute = match.captures[0].to_sym assoc_klass = nil begin assoc_klass = association.to_s.classify.constantize rescue assoc_klass = association_reflection[1].[:class_name].constantize end unless assoc_klass.columns_hash.has_key?( attribute.to_s ) || assoc_klass.public_instance_methods.include?( attribute.to_s ) if match.captures.empty? || match.captures.size > 2 raise NoMethodError.new('has_associative_facades could find no ' + "#{assoc_klass.name}##{method} " + 'method to resolve ' + "#{self.class.name}##{method}", method, args) end end self.class.class_eval <<-END def #{method_name} return self.send( :#{association} ).send( :#{attribute} ) unless self.send( :#{association} ).nil? nil end END return self.send( method_name ) end raise NoMethodError.new('has_associative_facades failed to resolve ' + "#{self.class.name}##{method} via " + "any association on #{self.class.name}", method, args) end |