ruby-on-rails - foreign - rails multiple table inheritance
ActiveRecord:: SubclassNotFound: el mecanismo de herencia de tabla Ășnica no pudo localizar la subclase (5)
Soy novato en Rails.
Tengo dos modelos Categoría y Producto de la siguiente manera: -
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
Y mi schema.rb es el siguiente:
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
En la consola de Rails creé dos productos con dos productos con el comando 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">]`
Y creó dos categorías con el comando Category.create en la consola
<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">
Ahora, Product.all funciona bien pero Category.all da
ActiveRecord :: SubclassNotFound: el mecanismo de herencia de tabla única no logró ubicar la subclase: ''clothing''. Este error se plantea porque la columna ''tipo'' está reservada para almacenar la clase en caso de herencia. Cambie el nombre de esta columna si no pretendía que se utilizara para almacenar la clase de herencia o sobreescriba Category.inheritance_column para usar otra columna para esa información.
¿Qué pasa allí? Quiero hacer una relación entre Categoría y Producto como
una categoría tiene_muchos productos y productos pertenece_ a una categoría.
Acabo de encontrar esta publicación al intentar encontrar una solución a mi propio problema con este type
palabra de reserva, así que quizás esto pueda ayudar a otra persona.
Cambiar el nombre de la columna no es una solución fácil para mí porque estoy trabajando en un sistema completo existente que migra a un registro activo de mongodb.
Encontré agregar self.inheritance_column = :_type_disabled
al modelo con el nombre de la columna ofensiva corregido el error que encontré here .
Sé que no estamos usando ninguna herencia, así que creo que está bien que lo haga, pero no sé qué otras implicaciones podría haber debido a eso. Si alguien más tiene alguna opinión sobre esto, estaría interesado en saberlo.
Si puedes cambiar el nombre de la columna y evitar hacer esto, entonces esa es una solución mucho mejor, estoy seguro.
Intenta usar inheritance_column, luego escribe no será más reservado:
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
Si encontró esta pregunta porque encontró el mismo error y está utilizando Rails STI, pero obtuvo el error porque estaba tratando de cambiar el nombre de las subclases heredadas, es probable que sea porque tiene datos antiguos en la columna de type
y olvidó actualizarlo . Entonces esta tarea de rake podría ayudar:
update_category_type_column_with_new_subclass_names.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
si alguien realmente está tratando de llevar a cabo STI, intente agregar una nueva clase que herede del padre, y el mensaje de error en cuestión debería desaparecer.
class YourSubclass < Category
end
type
es palabra restringida, no se puede usar como nombre de columna en los modelos de ActiveRecord (a menos que esté haciendo STI).