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 " def \#{assoc}(*args)\n options = args.extract_options!\n options = options.with_indifferent_access\n # Raise an error if we have multiple args and options\n raise \"Invalid arguments to \#{assoc}\" unless options.blank? || args.length == 1\n args.each do |arg|\n klass_name = (options[:class_name] ? options[:class_name].to_s.classify : arg.to_s.classify)\n # add this to any descendants - the other methods etc are handled by inheritance\n ([self] + self.descendants).each do |klass|\n #We need to merge upon itself to generate a new object since the children all share their related objects with each other\n klass.related_objects = klass.related_objects.merge(:\#{assoc} => klass.related_objects[:\#{assoc}].merge(arg.to_sym => klass_name))\n end\n # We need to define reader and writer methods here\n define_association_as_attribute(:\#{assoc}, arg, options)\n end\n end\n\n def \#{assoc}?(name)\n return self.related_objects[:\#{assoc}][name.to_s.pluralize.to_sym].present? || self.related_objects[:\#{assoc}][name.to_s.singularize.to_sym].present?\n end\n\n def \#{assoc}_class_name(name)\n raise \"No such\" + :\#{assoc}.to_s + \" association on \#{name}\" unless self.\#{assoc}?(name)\n return self.find_namespaced_class_name(self.related_objects[:\#{assoc}][name.to_sym])\n end\n\n EOE\n # For convenience we will define the methods for testing for the existence of an association\n # and getting the class for an association as instance methods too to avoid tons of self.class calls\n self.class_eval <<-EOE, __FILE__, __LINE__ + 1\n def \#{assoc}?(name)\n return self.class.\#{assoc}?(name)\n end\n\n def \#{assoc}_class_name(name)\n return self.class.\#{assoc}_class_name(name)\n end\n EOE\n end\nend\n", __FILE__, __LINE__ + 1 |