我正在使用Ruby on Rails 2.3.10。我有一个班级,School
。我使用STI为我提供了几个子类:PrimarySchool
,SecondarySchool
和University
。
app/models/primary_school.rb:
class PrimarySchool < School
has_many :education_records, :foreign_key => "school_id"
end
app/models/secondary_school.rb:
class SecondarySchool < School
has_many :education_records, :foreign_key => "school_id"
end
app/models/university.rb
class University < School
has_and_belongs_to_many :applicants, :join_table => :applicants_schools, :foreign_key => "school_id"
end
db/migrate/20100824170203_create_schools.rb:
class CreateSchools < ActiveRecord::Migration
def self.up
create_table :schools do |t|
t.string :name
t.string :type # secondary, cegep, college, university
t.string :street
...
t.timestamps
end
end
def self.down
drop_table :schools
end
end
PrimarySchool.first
和PrimarySchool.last
按预期工作。 SecondarySchool.first
和SecondarySchool.last
按预期工作。 University.last
有效。
但是,University.first
和University.all
会引发ActiveRecord::SubclassNotFound
例外:
ActiveRecord::SubclassNotFound: The single-table inheritance mechanism failed to locate the subclass: 'University'. 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 University.inheritance_column to use another column for that information.
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.10/lib/active_record/base.rb:1671:in `instantiate'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.10/lib/active_record/base.rb:665:in `find_by_sql'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.10/lib/active_record/base.rb:665:in `collect!'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.10/lib/active_record/base.rb:665:in `find_by_sql'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.10/lib/active_record/base.rb:1582:in `find_every'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.10/lib/active_record/base.rb:619:in `find'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.10/lib/active_record/base.rb:639:in `all'
from (irb):6
from :0
生成的SQL是正确的:
SecondarySchool Load (0.3ms) SELECT * FROM `schools` WHERE ( (`schools`.`type` = 'University' ) ) LIMIT 1
SecondarySchool Load (1.7ms) SELECT * FROM `schools` WHERE ( (`schools`.`type` = 'University' ) ) ORDER BY schools.id DESC LIMIT 1
我错过了什么/做错了什么?
答案 0 :(得分:3)
这是开发模式中的known issue。
一种解决方法是在基类文件的底部注册子类。
%w(secondary_school university).each do |r|
require_dependency r
end if Rails.env.development?
答案 1 :(得分:2)
KandadaBoggu让我走上正轨。 Pete P.的解决方法对我有用:
class School < ActiveRecord::Base
def self.subclasses
[PrimarySchool, SecondarySchool, OtherSchool, University]
end
end
因为它摆脱了异常......但它生成了错误的SQL:
SELECT * FROM `schools` WHERE ( (`schools`.`type` = 'University' OR
`schools`.`type` = 'PrimarySchool' OR `schools`.`type` = 'SecondarySchool' OR
`schools`.`type` = 'OtherSchool' OR `schools`.`type` = 'PostSecondaryInstitution' OR
`schools`.`type` = 'Cegep' OR `schools`.`type` = 'College' OR `schools`.`type` =
'University' ) ) LIMIT 1
将university.rb重命名为uni.rb,更改类名和UPDATEing类型列使这项工作成功。我真的很困惑。