
STI issue when loading Resources via base Model
Reported by phatmann | October 14th, 2009 @ 03:25 PM | in 1.1
The following code shows the problem:
require 'rubygems'
gem 'dm-core', '0.10.1'
require 'dm-core'
DataMapper::Logger.new(STDOUT, :debug)
DataMapper.setup(:default, "mysql://localhost/ts_test")
class Base
include DataMapper::Resource
property :id, Serial
property :type, Discriminator
end
class Derived1 < Base
end
class Derived2 < Base
property :extra, Integer
end
DataMapper.auto_migrate!
Derived2.create(:extra => 1)
Derived2.all.first.extra # SUCCEEDS
Base.all.first.extra # FAILS
Here is the backtrace:
`+options[:field]+ entry :extra does not map to a property in Base (ArgumentError)`
dm-core/query.rb:689:in `assert_valid_fields'
dm-core/query.rb:680:in `each'
dm-core/query.rb:680:in `assert_valid_fields'
dm-core/query.rb:656:in `assert_valid_options'
dm-core/query.rb:654:in `each'
dm-core/query.rb:654:in `assert_valid_options'
dm-core/query.rb:598:in `initialize'
dm-core/query.rb:343:in `update'
dm-core/query.rb:359:in `merge'
dm-core/collection.rb:69:in `reload'
dm-core/resource.rb:724:in `eager_load'
dm-core/resource.rb:710:in `lazy_load'
dm-core/property.rb:596:in `send'
dm-core/property.rb:596:in `lazy_load'
dm-core/property.rb:487:in `get'
dm-core/model/property.rb:200:in `extra'
from dm-test.rb:24
The problem starts with an STI issue: the first resource returned from Base.all does not have the :extra field loaded. Attempting to access the :extra field triggers a lazy load, which then triggers an eager load. The eager loading code loads the resource as type Base rather than Derived2, and the call to the #extra accessor fails.
So there are at least problems here:
-
All the fields of Derived2 are not properly loaded when accessing via Base.all.first
-
Eager loading via Base.all does not honor the STI type
Comments and changes to this ticket
-
David Kelso January 15th, 2010 @ 01:02 AM
Hey there. Looks like a dupe of this bug I filed a while ago:
http://datamapper.lighthouseapp.com/projects/20609-datamapper/ticke... -
Martin Gamsjaeger (snusnu) January 14th, 2011 @ 08:47 PM
- State changed from new to resolved
- Milestone set to 1.1
- Milestone order changed from 0 to 0
It's not exactly a dupe, in fact I believe this is resolved. Have a look at my comment over at #911 tho.
ree-1.8.7-2010.02@datamapper mungo:dm-core snusnu$ ruby 1095.rb ~ (0.000107) SELECT sqlite_version(*) ~ (0.000135) DROP TABLE IF EXISTS "bases" ~ (0.000013) PRAGMA table_info("bases") ~ (0.000314) CREATE TABLE "bases" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "type" VARCHAR NOT NULL, "extra" INTEGER) ~ (0.000075) DROP TABLE IF EXISTS "bases" ~ (0.000007) PRAGMA table_info("bases") ~ (0.000102) CREATE TABLE "bases" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "type" VARCHAR NOT NULL, "extra" INTEGER) ~ (0.000071) DROP TABLE IF EXISTS "bases" ~ (0.000006) PRAGMA table_info("bases") ~ (0.000108) CREATE TABLE "bases" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "type" VARCHAR NOT NULL, "extra" INTEGER) ~ (0.000041) INSERT INTO "bases" ("type", "extra") VALUES ('Derived2', 1) ~ (0.000039) SELECT "id", "type", "extra" FROM "bases" WHERE "type" IN ('Derived2') ORDER BY "id" LIMIT 1 ~ (0.000041) SELECT "id", "type" FROM "bases" WHERE "type" IN ('Base', 'Derived1', 'Derived2') ORDER BY "id" LIMIT 1 ~ (0.000034) SELECT "id", "type", "extra" FROM "bases" WHERE "id" = 1 ORDER BY "id"
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 »