Ruby on rails ActiveRecord::SubclassNotFound:单表继承机制未能找到该子类
我是Rails的新手。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
我有两种型号类别和产品,如下所示:
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如果您可以更改列名并避免这样做,那么我相信这是一个更好的解决方案。如果您发现这个问题是因为遇到了相同的错误,并且您实际使用的是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