Skip to content

Instantly share code, notes, and snippets.

Created January 26, 2009 23:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/53037 to your computer and use it in GitHub Desktop.
Save anonymous/53037 to your computer and use it in GitHub Desktop.
DataMapper finders are supposed to be chainable, so that
Model.all(:conditions).all(:conditions).all(:conditions) or
equivalent should only perform one query. Additionally, (and
I can't find it in the docs) chained finders also have access
to class methods, such that Finger.all(...).long (given the
above code) still returns a valid chained association.
http://datamapper.org/doku.php?id=docs:associations#finders_off_associations suggests that associations should also return chainable finders, which
it does. @hand.fingers.all(...) seems to work just fine.
However, @hand.fingers.long, which I expect to work, seems to
be running two queries - one on just the association (which
is never used) and then another when the final chained
association is used.
require 'rubygems'
require 'dm-core'
DataMapper.setup(:default, 'sqlite3::memory:')
class Hand
include DataMapper::Resource
property :id, Serial
has n, :fingers
end
class Finger
include DataMapper::Resource
property :id, Serial
property :name, String
belongs_to :hand
def self.long
all(:conditions => ["name <> ?", 'thumb'])
end
end
DataMapper.auto_migrate!
hand = Hand.new()
hand.save
hand.fingers.build(:name => 'thumb').save
hand.fingers.build(:name => 'index').save
hand.fingers.build(:name => 'middle').save
hand.fingers.build(:name => 'ring').save
hand.fingers.build(:name => 'pinky').save
DataObjects::Sqlite3.logger = DataObjects::Logger.new(STDOUT, :debug)
hand = Hand.first
# SELECT "id" FROM "hands" ORDER BY "id" LIMIT 1
puts
p hand.fingers.all(:conditions => ["name <> ?", 'thumb']).map{|finger| finger.name}
# SELECT "id", "name", "hand_id" FROM "fingers" WHERE ("hand_id" IN (1)) AND name <> 'thumb' ORDER BY "id"
puts
p hand.fingers.long.map{|finger| finger.name}
# SELECT "id", "name", "hand_id" FROM "fingers" WHERE ("hand_id" IN (1)) ORDER BY "id"
# SELECT "id", "name", "hand_id" FROM "fingers" WHERE ("hand_id" = 1) AND name <> 'thumb' ORDER BY "id" DESC
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment