Skip to content

Commit

Permalink
Fix bugs \#444 and \#566 and \#577 which all had the same cause
Browse files Browse the repository at this point in the history
This basically tries to make relationship initalization a bit smarter.
The code is pretty ugly, but it just tries loading up relations until
they work (that is, all related objects are loaded). This is done
for every Model#properties call, but of course cached once they are
in a sane state.
  • Loading branch information
dbussink committed Sep 27, 2008
1 parent d7becaa commit 4384aa0
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
5 changes: 3 additions & 2 deletions lib/dm-core/associations.rb
Expand Up @@ -45,8 +45,8 @@ def many_to_one_relationships
end

def relationships(repository_name = default_repository_name)
@relationships ||= Hash.new { |h,k| h[k] = k == Repository.default_name ? {} : h[Repository.default_name].dup }
@relationships[repository_name]
@relationships ||= {}
@relationships[repository_name] ||= repository_name == Repository.default_name ? {} : relationships(Repository.default_name).dup
end

def n
Expand Down Expand Up @@ -145,6 +145,7 @@ def has(cardinality, name, options = {})
#
# @api public
def belongs_to(name, options={})
@_valid_relations = false
relationship = ManyToOne.setup(name, self, options)
# Please leave this in - I will release contextual serialization soon
# which requires this -- guyvdb
Expand Down
15 changes: 15 additions & 0 deletions lib/dm-core/model.rb
Expand Up @@ -154,6 +154,7 @@ def property(name, type, options = {})
create_property_setter(property)

properties(repository_name)[property.name] = property
@_valid_relations = false

# Add property to the other mappings as well if this is for the default
# repository.
Expand Down Expand Up @@ -195,6 +196,20 @@ def repositories
end

def properties(repository_name = default_repository_name)
# We need to check whether all relations are already set up.
# If this isn't the case, we try to reload them here
if !@_valid_relations && respond_to?(:many_to_one_relationships)
@_valid_relations = true
begin
many_to_one_relationships.each do |r|
r.child_key
end
rescue NameError
# Apparently not all relations are loaded,
# so we will try again later on
@_valid_relations = false
end
end
@properties[repository_name] ||= repository_name == Repository.default_name ? PropertySet.new : properties(Repository.default_name).dup
end

Expand Down
14 changes: 13 additions & 1 deletion spec/integration/association_spec.rb
Expand Up @@ -302,6 +302,18 @@ def self.default_repository_name
area.should respond_to(:machine=)
end

it 'should create the foreign key property immediately' do
class Duck
include DataMapper::Resource
property :id, Serial
belongs_to :sky
end
Duck.properties.slice(:sky_id).compact.should_not be_empty
duck = Duck.new
duck.should respond_to(:sky_id)
duck.should respond_to(:sky_id=)
end

it 'should load without the parent'

it 'should allow substituting the parent' do
Expand Down Expand Up @@ -331,7 +343,7 @@ class Ostrich
end
end

FlightlessBirds::Ostrich.properties.slice(:sky_id).should_not be_empty
FlightlessBirds::Ostrich.properties(ADAPTER).slice(:sky_id).compact.should_not be_empty
end
end

Expand Down

0 comments on commit 4384aa0

Please sign in to comment.