diff --git a/lib/dm-core/model.rb b/lib/dm-core/model.rb index d4e377e70..3e7a8e787 100644 --- a/lib/dm-core/model.rb +++ b/lib/dm-core/model.rb @@ -209,11 +209,12 @@ def self.extra_extensions def self.extended(descendant) descendants << descendant - descendant.instance_variable_set(:@valid, false) - descendant.instance_variable_set(:@base_model, descendant) - descendant.instance_variable_set(:@storage_names, {}) - descendant.instance_variable_set(:@default_order, {}) - + descendant.instance_eval do + @valid = false unless instance_variable_defined?(:@valid) + @base_model ||= descendant + @storage_names ||= {} + @default_order ||= {} + end descendant.extend(Chainable) extra_extensions.each { |mod| descendant.extend(mod) } @@ -224,6 +225,11 @@ def self.extended(descendant) def inherited(descendant) descendants << descendant + descendant.instance_eval do + @valid = false unless instance_variable_defined?(:@valid) + @base_model ||= base_model + end + descendant.instance_variable_set(:@valid, false) descendant.instance_variable_set(:@base_model, base_model) descendant.instance_variable_set(:@storage_names, @storage_names.dup) diff --git a/lib/dm-core/model/property.rb b/lib/dm-core/model/property.rb index 09fa15aee..fcc692675 100644 --- a/lib/dm-core/model/property.rb +++ b/lib/dm-core/model/property.rb @@ -7,13 +7,17 @@ module Property Model.append_extensions self, DataMapper::Property::Lookup def self.extended(model) - model.instance_variable_set(:@properties, {}) - model.instance_variable_set(:@field_naming_conventions, {}) + model.instance_eval do + @properties = {} + @field_naming_conventions ||= {} + end end def inherited(model) - model.instance_variable_set(:@properties, {}) + model.instance_eval do + @properties ||= {} + end model.instance_variable_set(:@field_naming_conventions, @field_naming_conventions.dup) @properties.each do |repository_name, properties| diff --git a/lib/dm-core/model/relationship.rb b/lib/dm-core/model/relationship.rb index aeb5380ae..ec1c2cd15 100644 --- a/lib/dm-core/model/relationship.rb +++ b/lib/dm-core/model/relationship.rb @@ -17,7 +17,9 @@ module Relationship # # @api private def self.extended(model) - model.instance_variable_set(:@relationships, {}) + model.instance_eval do + @relationships ||= {} + end end # When DataMapper model is inherited, relationships @@ -25,7 +27,9 @@ def self.extended(model) # # @api private def inherited(model) - model.instance_variable_set(:@relationships, {}) + model.instance_eval do + @relationships ||= {} + end @relationships.each do |repository_name, relationships| model_relationships = model.relationships(repository_name) diff --git a/spec/public/model/relationship_spec.rb b/spec/public/model/relationship_spec.rb index 2cacfc57b..ae5eaaf2c 100644 --- a/spec/public/model/relationship_spec.rb +++ b/spec/public/model/relationship_spec.rb @@ -1038,3 +1038,64 @@ class ::Company end end end + +describe DataMapper::Associations do + before :all do + module ::Vehicle + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods + + def vehicle_with_wheels(*args) + include DataMapper::Resource + + property :id, DataMapper::Property::Serial + property :license_plate, String + end + end + end + + class Exhaust + include DataMapper::Resource + + property :id, Serial + belongs_to :car + end + + class Suspension + include DataMapper::Resource + + property :id, Serial + property :brand, String + end + + class Car + include DataMapper::Resource + has n, :suspensions + end + + class Car + include DataMapper::Resource + include Vehicle + + vehicle_with_wheels + + property :number_of_seats, Integer + has n, :exhausts + + end + + DataMapper.finalize + end + + it "should have all relationships when Resource is included once" do + Exhaust.relationships.any? {|r| r.name == :car }.should be_true + end + + it "should not forget about relationships when Resource is included more than once" do + Car.relationships.any? {|r| r.name == :exhausts }.should be_true + Car.relationships.any? {|r| r.name == :suspensions }.should be_true + end +end