Module: ApiResource::Associations::ClassMethods
- Defined in:
- lib/api_resource/associations.rb
Instance Method Summary collapse
- #association?(assoc) ⇒ Boolean
- #association_class(assoc) ⇒ Object
- #association_class_name(assoc) ⇒ Object
-
#association_foreign_key_field(assoc, type = nil) ⇒ Object
TODO: add a special foreign_key option to associations.
- #association_names ⇒ Object
-
#define_association_methods ⇒ Object
Define the methods for creating and testing for associations, unfortunately scopes are different enough to require different methods :(.
Instance Method Details
#association?(assoc) ⇒ Boolean
121 122 123 124 125 126 |
# File 'lib/api_resource/associations.rb', line 121 def association?(assoc) self..any? do |key, value| next if key.to_s == "scopes" value.detect { |k,v| k.to_sym == assoc.to_sym } end end |
#association_class(assoc) ⇒ Object
133 134 135 |
# File 'lib/api_resource/associations.rb', line 133 def association_class(assoc) self.association_class_name(assoc).constantize end |
#association_class_name(assoc) ⇒ Object
137 138 139 140 141 142 143 |
# File 'lib/api_resource/associations.rb', line 137 def association_class_name(assoc) raise ArgumentError, "#{assoc} is not a valid association of #{self}" unless self.association?(assoc) result = self..detect do |key,value| ret = value.detect{|k,v| k.to_sym == assoc.to_sym } return self.find_namespaced_class_name(ret[1]) if ret end end |
#association_foreign_key_field(assoc, type = nil) ⇒ Object
TODO: add a special foreign_key option to associations
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/api_resource/associations.rb', line 146 def association_foreign_key_field(assoc, type = nil) if type.nil? && has_many?(assoc) type = :has_many else type = type.to_s.to_sym end # for now just use the association name str = assoc.to_s.singularize.foreign_key if type.to_s =~ /^has_many/ str = str.pluralize end str.to_sym end |
#association_names ⇒ Object
128 129 130 131 |
# File 'lib/api_resource/associations.rb', line 128 def association_names # structure is {:has_many => {"myname" => "ClassName"}} self..clone.delete_if{|k,v| k.to_s == "scopes"}.collect{|k,v| v.keys.collect(&:to_sym)}.flatten end |
#define_association_methods ⇒ Object
Define the methods for creating and testing for associations, unfortunately scopes are different enough to require different methods :(
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/api_resource/associations.rb', line 77 def define_association_methods self.association_types.each_key do |assoc| self.instance_eval <<-EOE, __FILE__, __LINE__ + 1 def #{assoc}(*args) options = args.extract_options! options = options.with_indifferent_access # Raise an error if we have multiple args and options raise "Invalid arguments to #{assoc}" unless options.blank? || args.length == 1 args.each do |arg| klass_name = (options[:class_name] ? options[:class_name].to_s.classify : arg.to_s.classify) # add this to any descendants - the other methods etc are handled by inheritance ([self] + self.descendants).each do |klass| #We need to merge upon itself to generate a new object since the children all share their related objects with each other klass.related_objects = klass.related_objects.merge(:#{assoc} => klass.related_objects[:#{assoc}].merge(arg.to_sym => klass_name)) end # We need to define reader and writer methods here define_association_as_attribute(:#{assoc}, arg, options) end end def #{assoc}?(name) return self.related_objects[:#{assoc}][name.to_s.pluralize.to_sym].present? || self.related_objects[:#{assoc}][name.to_s.singularize.to_sym].present? end def #{assoc}_class_name(name) raise "No such" + :#{assoc}.to_s + " association on #{name}" unless self.#{assoc}?(name) return self.find_namespaced_class_name(self.related_objects[:#{assoc}][name.to_sym]) end EOE # For convenience we will define the methods for testing for the existence of an association # and getting the class for an association as instance methods too to avoid tons of self.class calls self.class_eval <<-EOE, __FILE__, __LINE__ + 1 def #{assoc}?(name) return self.class.#{assoc}?(name) end def #{assoc}_class_name(name) return self.class.#{assoc}_class_name(name) end EOE end end |