
loading associated objects fails
Reported by Rob Westgeest | September 18th, 2008 @ 06:49 AM
Hi,
Take the following situation. Book has loans and a loan belongs to a person. Kind of like the post, tag, tagging example. However not using :through.
Then when a loan fetched through the associated book, the associated person is nil when accessed for the first time.
This is not reproducable (to the best of my knowledge) in memory. You have to have a real database. I have added the database file, but you can easily create it by enabling the aaaa spec.
So in the underlying specs the first one is failing and the second one is passing - and they are exactly the same:
require 'rubygems'
require 'dm-core'
DataMapper.setup(:default, :adapter => 'sqlite3', :database => 'library.db')
class Person
include DataMapper::Resource
property :id, Integer, :serial => true
property :name, String
has n, :loans
end
class Loan
include DataMapper::Resource
property :id, Integer, :serial => true
# property
belongs_to :book
belongs_to :person
end
class Book
include DataMapper::Resource
property :id, Integer, :serial => true
property :title, String
has n, :loans
end
describe 'DataMapper association', 'loading' do
before(:each) do
end
# it "aaaa" do
# DataMapper.auto_migrate!
# b = Book.create :title => 'lord of the rings'
# b2 = Book.create :title => 'singing detective'
# p1 = Person.create :name => 'david shorewall'
# p2 = Person.create :name => 'hank peacock'
# b.loans.create :person => p1
# b2.loans.create :person => p2
# end
it "fails to load secundary association the first time" do
Book.get(1).loans[0].person.should_not be_nil
end
it "loads it when accessed the second time " do
Book.get(2).loans[0].person.should_not be_nil
end
end
At first it seemed related to the STI problem, but i quess it is different.
Comments and changes to this ticket
-
Rob Westgeest September 19th, 2008 @ 06:46 AM
Btw if you change the spec to exacly identical specs, the results are the same.
it "fails to load secundary association the first time" do
Book.get(1).loans[0].person.should_not be_nil
end
it "loads it when accessed the second time " do
Book.get(1).loans[0].person.should_not be_nil
end
cheers
-
Rob Westgeest September 19th, 2008 @ 03:21 PM
I found out about logging sql statements. The first spec outputs this:
Fri, 19 Sep 2008 20:05:40 GMT ~ debug ~ SELECT "id", "title" FROM "books" WHERE ("id" = 1) ORDER BY "id" LIMIT 1 Fri, 19 Sep 2008 20:05:40 GMT ~ debug ~ SELECT "id", "book_id" FROM "loans" WHERE ("book_id" IN (1)) ORDER BY "id" Fri, 19 Sep 2008 20:05:40 GMT ~ debug ~ SELECT "id", "book_id" FROM "loans" WHERE ("book_id" = 1) AND ("id" IN (1)) ORDER BY "id" $$$ Now it seems that the person_id is not in the sql statements. Whereas in the second spec it is, see:
Fri, 19 Sep 2008 20:05:40 GMT ~ debug ~ SELECT "id", "title" FROM "books" WHERE ("id" = 2) ORDER BY "id" LIMIT 1 Fri, 19 Sep 2008 20:05:40 GMT ~ debug ~ SELECT "id", "book_id", "person_id" FROM "loans" WHERE ("book_id" IN (2)) ORDER BY "id" Fri, 19 Sep 2008 20:05:40 GMT ~ debug ~ SELECT "id", "name" FROM "people" WHERE ("id" IN (2)) ORDER BY "id"
I just hopes this helps someone to get to the cause of the problem. More info: I you would get a loan by @@@l = Loan.get 1
and access the book and then the person like so @@@l.book l.person
then book is not nil but person is. Would you be doing this the other way around like so @@@l.person l.book
Then book is nil and person is not.
In both cases: try @@@l = Loan.get(1)
again and every thing is fine. Cause of this (at least a direction towards the cause): as pointed out, the query forgets to include person_id in the first example and book_id in the second one.
-
-
Dirkjan Bussink September 27th, 2008 @ 07:42 AM
Could you please test whether this is fixed now? I think it's the same bug as #444
-
Dirkjan Bussink October 7th, 2008 @ 02:51 PM
- State changed from new to 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 »