lib/api_resource/associations.rb in api_resource-0.3.1 vs lib/api_resource/associations.rb in api_resource-0.3.2
- old
+ new
@@ -17,32 +17,53 @@
module Associations
extend ActiveSupport::Concern
included do
- raise "Cannot include Associations without first including AssociationActivation" unless self.ancestors.include?(ApiResource::AssociationActivation)
- class_attribute :related_objects
-
- # Hash to hold onto the definitions of the related objects
- self.related_objects = RelatedObjectHash.new
- self.association_types.keys.each do |type|
- self.related_objects[type] = RelatedObjectHash.new({})
+ unless self.ancestors.include?(ApiResource::AssociationActivation)
+ raise Exception.new(
+ "Can't include Associations without AssociationActivation"
+ )
end
- self.related_objects[:scope] = RelatedObjectHash.new({})
-
+
+ class_attribute :related_objects
+ self.clear_related_objects
+
+ # we need to add an inherited method here, but it can't happen
+ # until after this module in included/extended, so it's in its own
+ # little mini module
+ extend InheritedMethod
+
self.define_association_methods
end
# module methods to include the proper associations in various libraries - this is usually loaded in Railties
def self.activate_active_record
ActiveRecord::Base.class_eval do
include ApiResource::AssociationActivation
- self.activate_associations(:has_many_remote => :has_many_remote, :belongs_to_remote => :belongs_to_remote, :has_one_remote => :has_one_remote)
+ self.activate_associations(
+ :has_many_remote => :has_many_remote,
+ :belongs_to_remote => :belongs_to_remote,
+ :has_one_remote => :has_one_remote
+ )
end
end
+ module InheritedMethod
+ # define a method to reset our related objects
+ def inherited(descendant)
+ # we only want to do this in direct descendants of ApiResoruce::Base
+ if self == ApiResource::Base
+ descendant.clear_related_objects
+ else
+ descendant.clone_related_objects
+ end
+ super(descendant)
+ end
+ end
+
module ClassMethods
# Define the methods for creating and testing for associations, unfortunately
# scopes are different enough to require different methods :(
def define_association_methods
@@ -107,16 +128,29 @@
ret = value.detect{|k,v| k.to_sym == assoc.to_sym }
return self.find_namespaced_class_name(ret[1]) if ret
end
end
- def clear_associations
- self.related_objects.each do |_, val|
- val.clear
- end
- end
-
protected
+
+ def clear_related_objects
+ # Hash to hold onto the definitions of the related objects
+ self.related_objects = RelatedObjectHash.new
+ self.association_types.keys.each do |type|
+ self.related_objects[type] = RelatedObjectHash.new({})
+ end
+ self.related_objects[:scope] = RelatedObjectHash.new({})
+ end
+
+ def clone_related_objects
+ # Hash to hold onto the definitions of the related objects
+ self.related_objects = self.related_objects.clone
+ self.association_types.keys.each do |type|
+ self.related_objects[type] = self.related_objects[type].clone
+ end
+ self.related_objects[:scope] = self.related_objects[:scope].clone
+ end
+
def define_association_as_attribute(assoc_type, assoc_name)
# set up dirty tracking for associations
self.class_eval <<-EOE, __FILE__, __LINE__ + 1
def #{assoc_name}
\ No newline at end of file