Skip to content

Instantly share code, notes, and snippets.

@jrafanie
Created November 11, 2011 23:25
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 jrafanie/1359653 to your computer and use it in GitHub Desktop.
Save jrafanie/1359653 to your computer and use it in GitHub Desktop.
type column reader not defined for STI until you access the column using [:type], read_attribute(:type), or create a new instance.
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :type
t.string :name
t.timestamps
end
end
end
Using a vanilla app via rails new with rails 3.1.1 with ruby 1.8.7-p352. This issue does not occur with ruby 1.9.2-p290.
1) Create a SubUser in dev mode:
joerafaniello@:~/Code/playground/rails311_type_method$ bundle exec rails c
Loading development environment (Rails 3.1.1)
ruby-1.8.7-p352 :001 > SubUser.create(:name => "Joe")
(0.1ms) BEGIN
SQL (52.9ms) INSERT INTO "users" ("created_at", "name", "type", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", Fri, 11 Nov 2011 23:04:59 UTC +00:00], ["name", "Joe"], ["type", "SubUser"], ["updated_at", Fri, 11 Nov 2011 23:04:59 UTC +00:00]]
(0.4ms) COMMIT
=> #<SubUser id: 1, type: "SubUser", name: "Joe", created_at: "2011-11-11 23:04:59", updated_at: "2011-11-11 23:04:59">
ruby-1.8.7-p352 :002 > User.first.type
User Load (0.5ms) SELECT "users".* FROM "users" LIMIT 1
=> "SubUser"
ruby-1.8.7-p352 :003 > exit
2) type method is defined on the Subuser instance until you exit
3) Start a console and find the SubUser and call type, which is not defined, so you get the ruby type method.
joerafaniello@:~/Code/playground/rails311_type_method$ bundle exec rails c
Loading development environment (Rails 3.1.1)
ruby-1.8.7-p352 :001 > User.first.type
User Load (0.4ms) SELECT "users".* FROM "users" LIMIT 1
(irb):1: warning: Object#type is deprecated; use Object#class
=> SubUser(id: integer, type: string, name: string, created_at: datetime, updated_at: datetime)
4) Accessing the type column directly through read_attribute or hash access loads the type method.
ruby-1.8.7-p352 :002 > u = User.first
User Load (0.4ms) SELECT "users".* FROM "users" LIMIT 1
=> #<SubUser id: 1, type: "SubUser", name: "Joe", created_at: "2011-11-11 23:04:59", updated_at: "2011-11-11 23:04:59">
ruby-1.8.7-p352 :003 > u[:type]
=> "SubUser"
ruby-1.8.7-p352 :004 > u.type
=> "SubUser"
ruby-1.8.7-p352 :005 > exit
5) Same test with production mode.
joerafaniello@:~/Code/playground/rails311_type_method$ bundle exec rails c production
Loading production environment (Rails 3.1.1)
ruby-1.8.7-p352 :001 > SubUser.create(:name => "Joe")
(0.1ms) BEGIN
SQL (3.0ms) INSERT INTO "users" ("created_at", "name", "type", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", Fri, 11 Nov 2011 23:07:00 UTC +00:00], ["name", "Joe"], ["type", "SubUser"], ["updated_at", Fri, 11 Nov 2011 23:07:00 UTC +00:00]]
(0.7ms) COMMIT
=> #<SubUser id: 2, type: "SubUser", name: "Joe", created_at: "2011-11-11 23:07:00", updated_at: "2011-11-11 23:07:00">
ruby-1.8.7-p352 :002 > User.first.type
User Load (0.4ms) SELECT "users".* FROM "users" LIMIT 1
=> "SubUser"
ruby-1.8.7-p352 :003 > exit
joerafaniello@:~/Code/playground/rails311_type_method$ bundle exec rails c production
Loading production environment (Rails 3.1.1)
ruby-1.8.7-p352 :001 > User.first.type
User Load (0.3ms) SELECT "users".* FROM "users" LIMIT 1
(irb):1: warning: Object#type is deprecated; use Object#class
=> SubUser(id: integer, type: string, name: string, created_at: datetime, updated_at: datetime)
ruby-1.8.7-p352 :002 > u = User.first
User Load (0.3ms) SELECT "users".* FROM "users" LIMIT 1
=> #<SubUser id: 1, type: "SubUser", name: "Joe", created_at: "2011-11-11 23:04:59", updated_at: "2011-11-11 23:04:59">
ruby-1.8.7-p352 :003 > u[:type]
=> "SubUser"
ruby-1.8.7-p352 :004 > u.type
=> "SubUser"
ruby-1.8.7-p352 :005 > exit
6) Creating a SubUser also will define the type method correctly so subsequent found instances have type.
joerafaniello@:~/Code/playground/rails311_type_method$ bundle exec rails c production
Loading production environment (Rails 3.1.1)
ruby-1.8.7-p352 :001 > SubUser.create(:name => "Joe2")
(0.1ms) BEGIN
SQL (3.1ms) INSERT INTO "users" ("created_at", "name", "type", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", Fri, 11 Nov 2011 23:09:50 UTC +00:00], ["name", "Joe2"], ["type", "SubUser"], ["updated_at", Fri, 11 Nov 2011 23:09:50 UTC +00:00]]
(0.5ms) COMMIT
=> #<SubUser id: 3, type: "SubUser", name: "Joe2", created_at: "2011-11-11 23:09:50", updated_at: "2011-11-11 23:09:50">
ruby-1.8.7-p352 :002 > u = User.find(1)
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
=> #<SubUser id: 1, type: "SubUser", name: "Joe", created_at: "2011-11-11 23:04:59", updated_at: "2011-11-11 23:04:59">
ruby-1.8.7-p352 :003 > u.type
=> "SubUser"
ruby-1.8.7-p352 :004 > u = User.find(2)
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 2]]
=> #<SubUser id: 2, type: "SubUser", name: "Joe", created_at: "2011-11-11 23:07:00", updated_at: "2011-11-11 23:07:00">
ruby-1.8.7-p352 :005 > u = User.find(3)
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 3]]
=> #<SubUser id: 3, type: "SubUser", name: "Joe2", created_at: "2011-11-11 23:09:50", updated_at: "2011-11-11 23:09:50">
ruby-1.8.7-p352 :006 > u.type
=> "SubUser"
class SubUser < User
end
class User < ActiveRecord::Base
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment