开发者

Chaining datamapper relationships across different repositories

class A
    include DataMapper::Resource

    def self.default_repository_name
        :alt_db
    end

    property :aid, Integer, :key => true
    # other stuff

    belongs_to :b, :model => 'B', :child_key => [ :bid ]

end

class B
    include DataMapper::Resource

    # this one is in the default repo

    property :bid, Integer, :key => true
    # other stuff

    belongs_to :c, :model => 'C', :child_key => [ :cid ]
end

class C
    include DataMapper::Resource

    # this one is in the default repo

    property :cid, Integer, :key => true
    # other stuff
end

If I just have A and B, this works fin开发者_运维问答e. If I add C, however, I get an error:

dm-core/model/property.rb:73:in `new': wrong number of arguments (4 for 3) (ArgumentError)

If I want to make a chain of relationships with DataMapper, so that I can give an ID in one place and get a piece of data that's, say, four tables away through a series of references to subsequent tables' primary key ID field, how can I do this?

EDIT: Digging into the DM source from the stack trace:

DataMapper.repository(other_repository_name) do
    properties << klass.new(self, name, options, type)
end

That's where the error is raised. Indeed, in this case klass is a DataMapper Integer property, and it's initialize method only accepts three options (model, name, and an options hash).

This whole block is only executed because I'm using more than one repository, though B and C are in the same one so I don't know if that sheds any light on why it's erroring on the cid property.

EDIT2:

I have tried all permutations, and it appears that when you're chaining, once you cross a database-boundary, that must be the end of the chain. For example, since A is :alt_db and B is :default, B is as deep as I can go, regardless of whether C is :default, :alt_db, or a third option.

If instead both A and B were :default, or both were :alt_db, and then C were the opposite one, C would be as deep as I could go.

I don't understand this behavior really, though.


You found a bug actually. It's been fixed in master. You can try grabbing sources from git and see if it works.


Your code works fine for me.

irb(main):001:0> A.first.b.c
  DEBUG - "(0.001168) SELECT "aid", "bid" FROM "as" ORDER BY "aid" LIMIT 1"
  DEBUG - "(0.000337) SELECT "bid", "cid" FROM "bs" WHERE "bid" = 2 LIMIT 1"
  DEBUG - "(0.000046) SELECT "cid" FROM "cs" WHERE "cid" = 3 LIMIT 1"
=> #<C @cid=3>

My gem is dm-core-1.1.0, you should check your version.


It turns out this was a small issue with DataMapper chaining across repositories. Submitted to them and it's allegedly been fixed already!

http://datamapper.lighthouseapp.com/projects/20609/tickets/1506-can-only-chain-up-to-first-time-changing-default-repository#ticket-1506-1

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜