Ruby on rails ActiveRecord::SubclassNotFound:单表继承机制未能找到该子类

Ruby on rails ActiveRecord::SubclassNotFound:单表继承机制未能找到该子类,ruby-on-rails,inheritance,rails-activerecord,Ruby On Rails,Inheritance,Rails Activerecord,我是Rails的新手。 我有两种型号类别和产品,如下所示: class Category < ActiveRecord::Base attr_accessible :type has_many :products end class Product < ActiveRecord::Base attr_accessible :category_id, :color, :price, :title belongs_to :category end ActiveRecord

我是Rails的新手。
我有两种型号类别产品,如下所示:

class Category < ActiveRecord::Base
 attr_accessible :type

 has_many :products
end

class Product < ActiveRecord::Base
 attr_accessible :category_id, :color, :price, :title

 belongs_to :category
end
ActiveRecord::Schema.define(:version => 20130725220046) do

create_table "categories", :force => true do |t|
    t.string   "type"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

  create_table "products", :force => true do |t|
    t.integer  "category_id"
    t.decimal  "price",       :precision => 10, :scale => 0
    t.string   "title"
    t.string   "color"
    t.datetime "created_at",                                 :null => false
    t.datetime "updated_at",                                 :null => false
  end

end
在Rails控制台中,我使用Product.create命令创建了两个产品和两个产品

[#<Product id: 1, category_id: 1, price: 500, title: "shirt", color: "blue", `created_at: "2013-07-25 22:04:54", updated_at: "2013-07-25 22:04:54">, #<Product id: 2, category_id: 1, price: 600, title: "tees", color: "black", created_at: "2013-07-25 22:05:17", updated_at: "2013-07-25 22:05:17">]`  

并使用控制台中的create命令创建了两个类别

<Category id: 1, type: "clothing", created_at: "2013-07-25 22:03:54", updated_at: "2013-07-25 22:03:54"><Category id: 2, type: "footwear", created_at: "2013-07-25 22:04:02", updated_at: "2013-07-25 22:04:02">  

现在,Product.all工作正常,但分类。all提供

ActiveRecord::SubclassNotFound:单表继承机制无法定位子类:“clothing”。引发此错误是因为列“type”是为在继承情况下存储类而保留的。如果您不打算将此列用于存储继承类或覆盖类别,请重命名此列。要使用另一列获取该信息,请单击“继承\”列

里面怎么了?我想在类别和产品之间建立一种关系,如

一个类别有许多产品,产品属于一个类别。

类型
是限定词,不能在ActiveRecord模型中将其用作列名(除非您正在进行STI)。

如果有人真的试图实现STI,请尝试添加从父类继承的新类,问题中的错误信息应该消失

class YourSubclass < Category
end
class-YourSubclass
尝试使用继承列,则类型将不再保留:

class Category < ActiveRecord::Base
 self.inheritance_column = :foo
 attr_accessible :type

 has_many :products
end

class Product < ActiveRecord::Base
 attr_accessible :category_id, :color, :price, :title

 belongs_to :category
end
类别
刚看到这篇文章时,我正试图找到一个解决我自己的问题的方法,用这个
类型
保留字,这样也许可以帮助其他人

更改列的名称对我来说不是一个简单的解决方案,因为我正在处理从mongodb迁移到active record的现有完整系统


我发现将
self.heritation\u column=:\u type\u disabled
添加到具有错误列名的模型中修复了我发现的错误

禁用STI

我不得不添加“self.heritation\u column”,而不是简单地添加 “继承_列”以使其正常工作。代码示例

类MyModel self.heritation\u column=:\u type\u已禁用结束

我知道我们没有使用任何继承,所以我认为这样做对我来说很好,但我不知道这会有什么其他影响。如果其他人对此有任何意见,我很想知道


如果您可以更改列名并避免这样做,那么我相信这是一个更好的解决方案。

如果您发现这个问题是因为遇到了相同的错误,并且您实际使用的是Rails STI,但由于尝试重命名继承的子类而出错,这可能是因为您在
type
列中有旧数据,但忘记了更新它。那么这个rake任务可能会有帮助:

使用新的子类名称更新类别类型列。rake

# This will be run when running `rake categories:update_type_column_with_new_subclass_names`
namespace :categories do
  desc 'Run through the categories with values in the type column and rename those according to the new subclass names: CategorySubclass1 -> CategorySubclass1NewName, CategorySubclass2 -> CategorySubclass2NewName, and CategorySubclass3 -> CategorySubclass3NewName . Run this rake task without arguments.'
  task update_type_column_with_new_subclass_names: :environment do
    Category.inheritance_column = :_type_disabled # to avoid getting error when using the type column: "ActiveRecord::SubclassNotFound: The single-table inheritance mechanism failed to locate the subclass: 'CategorySubclass1'"
    categories = Category.where("type <> '' AND type IS NOT NULL")
    categories.each do |a|
        begin
            case a.type
            when 'CategorySubclass1'
                a.type = 'CategorySubclass1NewName'
                a.save!
            when 'CategorySubclass2'
                a.type = 'CategorySubclass2NewName'
                a.save!
            when 'CategorySubclass3'
                a.type = 'CategorySubclass3NewName'
                a.save!
            end
        rescue StandardError => e
            puts '---'
            puts 'Error trying to set :type for category with :'
            puts 'id and url: '
            puts ' ' + a.id.to_s
            puts ' ' + a.type
            puts 'Error message: '
            puts e.message
            puts '---'
        end
    end
    Category.inheritance_column = :type # switch on the Rails STI after you've made your updates to the DB columns
  end
end
#运行` rake categories:update_type_column_与_new_subclass_名称"时将运行此命令`
名称空间:类别做什么
desc'在type列中运行带有值的类别,并根据新的子类名称重命名这些类别:CategorySubclass1->categorysubclassnewname、CategorySubclass2->CategorySubclass2NewName和CategorySubclass3->CategorySubclass3NewName。运行此rake任务时不带参数。”
任务更新\类型\列\带有\新\子类\名称::环境do
Category.heritation_column=:_type_disabled#为了避免在使用类型列时出错:“ActiveRecord::SubclassNotFound:单表继承机制未能找到子类:'CategorySubclass1'”
类别=类别。其中(“类型“”和类型不为空”)
类别。每个都有一个|
开始
案例a.类型
当“类别SubClass1”
a、 类型='CategorySubClassNewName'
a、 救命!
当“类别子类别2”
a、 类型='CategorySubclass2NewName'
a、 救命!
当“类别子类别3”
a、 类型='CategorySubclass3NewName'
a、 救命!
结束
营救标准错误=>e
放置'--'
放置“尝试设置类别的类型时出错:”
放置“id和url:”
将“+a.id”放入\u
将“”放入一个类型
放置“错误消息:”
放电子邮件
放置'--'
结束
结束
Category.heritation_column=:键入#在对DB列进行更新后切换Rails STI
结束
结束

如果当前AR模型未使用sti,则可以在模型内部设置
self.heritation\u column=:\u sti\u disabled
(或其他名称)

谢谢。现在我将“type”改为“name”。但当我先执行category=category.first,然后执行“category.products”时,它只显示id=1的产品。它应该显示该类别中的所有产品。
category.first.products
将始终返回(为简单起见,一个-数组,因为我不记得确切的类型名称)与此类别关联的所有产品。self.heritation\u column=nil在没有符号get的情况下工作。单表继承机制在执行此操作时无法定位子类“service”,这是自找麻烦。
self.heritation\u column=nil
仍在rails 4.2.7.1中工作。但我强烈建议不要使用名为
type