Skip to content
This repository has been archived by the owner on Apr 17, 2018. It is now read-only.

Commit

Permalink
Use the identity map for retrieving the parent resource in a many to …
Browse files Browse the repository at this point in the history
…one relationship
  • Loading branch information
dbussink committed Oct 24, 2010
1 parent f4b2f45 commit f4aff7c
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions lib/dm-core/associations/many_to_one.rb
Expand Up @@ -95,10 +95,18 @@ def source_scope(source)
def resource_for(source, other_query = nil)
query = query_for(source, other_query)

# TODO: lookup the resource in the Identity Map, and make sure
# it matches the query criteria, otherwise perform the query

target_model.first(query)
# If the target key is equal to the model key, we can use the
# Model#get so the IdentityMap is used
if target_key == target_model.key
target = target_model.get(*source_key.get!(source))
if query.conditions.matches?(target)
target
else
nil
end
else
target_model.first(query)
end
end

# Loads and returns association target (ex.: author) for given source resource
Expand Down Expand Up @@ -127,7 +135,7 @@ def get_collection(source)
# @param source [DataMapper::Resource]
# Child object (ex.: instance of article)
#
# @param source [DataMapper::Resource]
# @param target [DataMapper::Resource]
# Parent object (ex.: instance of author)
#
# @api semipublic
Expand Down

4 comments on commit f4aff7c

@snusnu
Copy link
Member

@snusnu snusnu commented on f4aff7c Oct 29, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are the specs? :P

@xaviershay
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seriously though how would you spec this? I need to put the same fix in for OneToOne...

@dkubb
Copy link
Member

@dkubb dkubb commented on f4aff7c Jan 11, 2011

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xaviershay: Hmm, maybe have two objects in a repository block that have the same parent, and check to make sure obj1.parent.equal?(obj2.parent) ?

That's the first thing that comes to mind. I wonder if it could work. I think the usage of an IM is incidental, the important behavior is that both objects reference the same parent.

@xaviershay
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this (or hopefully a cleaner version of it!) should work, but I couldn't get it to fail in spec/public/associations/many_to_one_spec.rb

describe 'loading the association using the Identity Map' do
  it 'uses the identity map' do
    comment2 = @comment_model.create(:body => 'Cool spec', :user => @user)
    repository do
      @user = @user_model.get(*@comment.user.key)
      @comment_model.get(*@comment.key).user.should equal(@user)
      @comment_model.get(*comment2.key).user.should equal(@user)
    end
  end
end

Please sign in to comment.