Help us understand the problem. What is going on with this article?

ActiveRecordで"type"という名前のカラムがあるとエラーが出る場合の対応

More than 5 years have passed since last update.

ActiveRecordで"type"というカラムをもつテーブルに接続し、取得系のメソッドを呼ぶと以下の様なエラーが出ます。

Table Kantais

id name type
1 金剛 戦艦
2 島風 駆逐艦
3 赤城 正規空母
[4] pry(main)> Kantai.find(1)
  Kantai Load (0.4ms)  SELECT `kantais`.* FROM `kantais` WHERE `kantais`.`id` = 1 LIMIT 1
ActiveRecord::SubclassNotFound: The single-table inheritance mechanism failed to locate the subclass: '戦艦'. This error is raised because the column 'type' is reserved for storing the class in case of inheritance. Please rename this column if you didn't intend it to be used for storing the inheritance class or overwrite Kantai.inheritance_column to use another column for that information.
from /Users/ryonext/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/activerecord-3.2.13/lib/active_record/inheritance.rb:143:in `rescue in find_sti_class'
[5] pry(main)> Kantai.all
  Kantai Load (0.3ms)  SELECT `kantais`.* FROM `kantais`
ActiveRecord::SubclassNotFound: The single-table inheritance mechanism failed to locate the subclass: '戦艦'. This error is raised because the column 'type' is reserved for storing the class in case of inheritance. Please rename this column if you didn't intend it to be used for storing the inheritance class or overwrite Kantai.inheritance_column to use another column for that information.
from /Users/ryonext/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/activerecord-3.2.13/lib/active_record/inheritance.rb:143:in `rescue in find_sti_class'

これはSTI(Single Table Inheritance)という1つのテーブルを複数のModelで利用する仕組みとして"type"という名前をActiveRecordが利用するからです。
エラーを見ると"type"をrenameしろと状況次第では難しい対処が書かれていますが、以下のようにすればカラム名を変更しなくても対応できます。

app/models/kantai.rb
class Kantai < ActiveRecord::Base
  attr_accessible :name, :type
  self.inheritance_column = :_type_disabled # この行を追加
end

これでアクセス可能になります。

[1] pry(main)> Kantai.all
  Kantai Load (1.8ms)  SELECT `kantais`.* FROM `kantais`
=> [#<Kantai id: 1, name: "金剛", type: "戦艦", created_at: "2013-11-26 13:55:20", updated_at: "2013-11-26 13:55:20">,
 #<Kantai id: 2, name: "島風", type: "駆逐艦", created_at: "2013-11-26 13:55:20", updated_at: "2013-11-26 13:55:20">,
 #<Kantai id: 3, name: "赤城", type: "正規空母", created_at: "2013-11-26 13:55:20", updated_at: "2013-11-26 13:55:20">]
[2] pry(main)> Kantai.find(1)
  Kantai Load (0.3ms)  SELECT `kantais`.* FROM `kantais` WHERE `kantais`.`id` = 1 LIMIT 1
=> #<Kantai id: 1, name: "金剛", type: "戦艦", created_at: "2013-11-26 13:55:20", updated_at: "2013-11-26 13:55:20">

補足

なお、"type"というカラムがあっても値が入ってなければ、上記の対応をしなくてもアクセスできてしまいます。開発中、データを埋めずに進めていて後になって明らかになる、ということがないようにご注意を。

app/models/kantai.rb
class Kantai < ActiveRecord::Base
  attr_accessible :name, :type
#  self.inheritance_column = :_type_disabled
end
[2] pry(main)> Kantai.all
  Kantai Load (0.3ms)  SELECT `kantais`.* FROM `kantais`
=> [#<Kantai id: 1, name: "金剛", type: nil, created_at: "2013-11-26 13:55:20", updated_at: "2013-11-26 13:55:20">,
 #<Kantai id: 2, name: "島風", type: nil, created_at: "2013-11-26 13:55:20", updated_at: "2013-11-26 13:55:20">,
 #<Kantai id: 3, name: "赤城", type: nil, created_at: "2013-11-26 13:55:20", updated_at: "2013-11-26 13:55:20">]
[3] pry(main)> Kantai.all
  Kantai Load (0.3ms)  SELECT `kantais`.* FROM `kantais`
=> [#<Kantai id: 1, name: "金剛", type: "", created_at: "2013-11-26 13:55:20", updated_at: "2013-11-26 13:55:20">,
 #<Kantai id: 2, name: "島風", type: "", created_at: "2013-11-26 13:55:20", updated_at: "2013-11-26 13:55:20">,
 #<Kantai id: 3, name: "赤城", type: "", created_at: "2013-11-26 13:55:20", updated_at: "2013-11-26 13:55:20">]
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away