LoginSignup
213
156

More than 5 years have passed since last update.

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

Posted at

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">]
213
156
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
213
156