
Stack exception accessing a many-to-one association
Reported by MarkMT | June 12th, 2009 @ 06:38 PM | in 0.10.0
A problem occurs when four conditions coincide -
(i) Given three models A, B and C, many-to-one relationships
exist between A and C and between B and C
(ii) The 'belongs_to :b' statement in the definition of the child
model C specifies the :classname for the parent model B.
(iii) The 'belongs_to :a' statement in C precedes the one
for B. (iv) The parent model A is loaded after the child
model C.
In this case, given an object, c, of class C, accessing the association c.a causes an infinite loop leading to a stack exception.
Detailed explanation here -
http://groups.google.com/group/datamapper/browse_thread/thread/503e...
Comments and changes to this ticket
-
Dan Kubb (dkubb) June 16th, 2009 @ 03:37 AM
- Assigned user set to Dan Kubb (dkubb)
- State changed from new to accepted
- Tag changed from association, many-to-one to association, many-to-one
- Milestone set to 0.10.0
-
Dan Kubb (dkubb) June 23rd, 2009 @ 01:37 AM
- State changed from accepted to hold
@Mark: Can you try to see if this problem persists with 0.10 RC1? The relationship code was completely rewritten, so there's a good chance this is no longer an issue at all.
If it is still a problem, can you attach a stand-alone script to this ticket that allows me to reproduce the problem at my end?
-
Martin Gamsjaeger (snusnu) July 9th, 2009 @ 02:09 PM
- State changed from hold to resolved
Mark,
I extracted a little standalone script (with a few modifications to make it 0.10 compliant) from the mailing list thread, ran it against current next branches as of today, and I don't get any errors. I marked this as resolved for 0.10, but if my script doesn't quite cover your usecase and/or you can still reproduce the error with next branches, feel free to comment and we can reopen it.
require "rubygems" require "dm-core" require "spec" DataMapper::Logger.new(STDOUT, :debug) DataMapper.setup(:default, "sqlite3::memory:") class User include DataMapper::Resource property :id, Serial has n, :recaps end class Recap include DataMapper::Resource property :id, Serial belongs_to :author, User belongs_to :regatta end class Regatta include DataMapper::Resource property :id, Serial has 1, :recap end describe "This setup" do before(:all) do DataMapper.auto_migrate! end it "should not recurse infinitely" do user = User.create regatta = Regatta.create recap = Recap.create :regatta => regatta, :author => user r = Recap.get(1) r.regatta.should == regatta end end # mungo:snippets snusnu$ spec -cfs markmt.rb # # This setup # ~ (0.000166) SELECT sqlite_version(*) # ~ (0.000108) DROP TABLE IF EXISTS "users" # ~ (0.000018) DROP TABLE IF EXISTS "recaps" # ~ (0.000026) DROP TABLE IF EXISTS "regattas" # ~ (0.000023) PRAGMA table_info("users") # ~ (0.000361) CREATE TABLE "users" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT) # ~ (0.000017) PRAGMA table_info("recaps") # ~ (0.000121) CREATE TABLE "recaps" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "author_id" INTEGER NOT NULL, "regatta_id" INTEGER NOT NULL) # ~ (0.000131) CREATE INDEX "index_recaps_regatta" ON "recaps" ("regatta_id") # ~ (0.000101) CREATE INDEX "index_recaps_author" ON "recaps" ("author_id") # ~ (0.000009) PRAGMA table_info("regattas") # ~ (0.000111) CREATE TABLE "regattas" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT) # ~ (0.000045) INSERT INTO "users" DEFAULT VALUES # ~ (0.000033) INSERT INTO "regattas" DEFAULT VALUES # ~ (0.000054) INSERT INTO "recaps" ("author_id", "regatta_id") VALUES (1, 1) # ~ (0.000028) SELECT "id", "author_id", "regatta_id" FROM "recaps" WHERE "id" = 1 # ~ (0.000038) SELECT "id" FROM "regattas" WHERE "id" = 1 ORDER BY "id" LIMIT 1 # - should not recurse infinitely # # Finished in 0.012402 seconds # # 1 example, 0 failures
-
MarkMT July 13th, 2009 @ 11:19 PM
Martin,
Thanks for looking into this... I haven't had a chance to try this with the next branch, but just looking at your script I think you've missed one condition that I noted in my google groups posting - in class Recap, the declaration 'belongs_to :regatta' has to precede 'belongs_to :author, User'. Yes it seems weird that that would matter, but this was one of the four conditions necessary for the failure I observed. Can you try that? Everything else in your script looks fine.
Mark.
-
Martin Gamsjaeger (snusnu) July 14th, 2009 @ 07:21 AM
Mark,
I just tried the snippet with the change you mentioned and it still behaves correctly! I think we can leave this resolved.
-
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »