Je suis novice chez Rails.
J'ai deux modèles Catégorie et Produit comme suit: -
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
Et mon schema.rb est le suivant: -
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
Dans la console Rails j'ai créé deux produits avec deux produits avec la commande 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">]`
Et créé deux catégories avec la commande Category.create dans la console
<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">
Maintenant, Product.all fonctionne bien mais Category.all donne
ActiveRecord :: SubclassNotFound: Le mécanisme d'héritage d'une table unique n'a pas pu localiser la sous-classe: "vêtements". Cette erreur est générée car la colonne 'type' est réservée au stockage de la classe en cas d'héritage. Veuillez renommer cette colonne si vous n'aviez pas l'intention de l'utiliser pour stocker la classe d'héritage ou remplacer Category.inheritance_column pour utiliser une autre colonne pour ces informations.
Qu'est-ce qui ne va pas là-dedans? Je veux faire une relation entre la catégorie et le produit comme
une catégorie a_de nombreux produits et produits appartient_ à une catégorie.
type
est Word restreint, vous ne pouvez pas l'utiliser comme nom de colonne dans les modèles ActiveRecord (sauf si vous faites STI).
Essayez d'utiliser inheritance_column, puis le type ne sera plus réservé:
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
Je suis juste tombé sur ce message en essayant de trouver une solution à mon propre problème avec ce type
mot de réserve, donc cela peut peut-être aider quelqu'un d'autre.
Changer le nom de la colonne n'est pas une solution facile pour moi car je travaille sur un système complet existant migrant vers l'enregistrement actif à partir de mongodb.
J'ai trouvé l'ajout de self.inheritance_column = :_type_disabled
au modèle avec le nom de colonne incriminé a corrigé l'erreur que j'ai trouvée ici .
Désactiver les IST
J'ai dû ajouter "self.inheritance_column" au lieu de simplement "inheritance_column" pour que cela fonctionne. Exemple de code
classe MyModel <ActiveRecord :: Base # disable STI
self.inheritance_column =: _type_disabled end
Je sais que nous n'utilisons aucun héritage, donc je pense que c'est bien pour moi de le faire, mais je ne sais pas quelles autres implications il pourrait y avoir à cause de cela. Si quelqu'un d'autre a des opinions à ce sujet, je serais intéressé de le savoir.
Si vous pouvez simplement changer le nom de la colonne et éviter de le faire, c'est une bien meilleure solution, j'en suis sûr.
si quelqu'un essaie réellement de supprimer STI, essayez d'ajouter une nouvelle classe qui hérite du parent, et le message d'erreur en question devrait disparaître.
class YourSubclass < Category
end
Si vous avez trouvé cette question parce que vous avez rencontré la même erreur et que vous utilisez en fait Rails STI, mais que vous avez obtenu l'erreur parce que vous essayez de renommer les sous-classes héritées, c'est probablement parce que vous avez d'anciennes données dans la colonne type
et j'ai oublié de le mettre à jour. Ensuite, cette tâche de râteau pourrait vous aider:
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
Vous pouvez définir à l'intérieur de votre modèle self.inheritance_column = :sti_disabled
(ou un autre nom) si vous n'utilisez pas STI pour le modèle AR actuel