2

我正在使用 Ruby on Rails 2.3.10。我有一堂课,School. 我使用 STI 给我​​几个子类PrimarySchoolSecondarySchoolUniversity.

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.firstUniversity.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

我错过了什么/做错了什么?

4

2 回答 2

3

这是开发模式中的一个已知问题

一种解决方法是在基类文件的底部注册子类。

%w(secondary_school university).each do |r| 
  require_dependency r
end if Rails.env.development?
于 2010-11-09T21:53:13.970 回答
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,更改类名并更新类型列使这项工作有效。我真的很困惑。

于 2010-11-09T22:17:06.517 回答