2013-07-26 5 views
29

Sono novizio di Rails.
Ho due modelli Categoria e prodotto come segue: -ActiveRecord :: SubclassNotFound: il meccanismo di ereditarietà a tabella singola non è riuscito a individuare la sottoclasse

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 

E il mio schema.rb è la seguente: -

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 

In console Rails ho creato due prodotti con due prodotti con lo Product.create comando

[#<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">]` 

e ha creato due categorie con il comando diCategory.create nella 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"> 

Ora, Product.all funziona bene, ma Category.all

ActiveRecord :: SubclassNotFound: il meccanismo di ereditarietà a tabella singola non è riuscito a individuare la sottoclasse: 'abbigliamento'. Questo errore viene generato perché la colonna 'tipo' è riservata per l'archiviazione della classe in caso di ereditarietà. Rinominare questa colonna se non si intende utilizzarlo per l'archiviazione della classe di ereditarietà o sovrascrivere Category.inheritance_column per utilizzare un'altra colonna per tali informazioni.

Cosa c'è che non va? Voglio fare una relazione tra Categoria e Prodotto come
una categoria has_many prodotti e prodotti appartiene a una categoria.

risposta

72

typetype è una parola con restrizioni, non è possibile utilizzarlo come nome di colonna nei modelli ActiveRecord (a meno che non si stia facendo STI).

+0

Grazie. Ora ho cambiato il 'tipo' in 'nome'. ma quando faccio category = Category.first e poi 'category.products' mostra solo il prodotto con id = 1.it dovrebbe mostrare tutti i prodotti in quella categoria. – mrudult

+0

'Category.first.products' restituirà sempre (una serie di - per semplicità perché non ricordo il nome esatto del tipo) tutti i prodotti associati a questa categoria. –

+0

Yup ha avuto qualche errore di battitura. Funziona bene. – mrudult

2

se qualcuno sta in realtà cercando di tirare fuori STI, prova ad aggiungere una nuova classe che eredita dal genitore, e il messaggio di errore in questione dovrebbe andare via.

class YourSubclass < Category 
end 
17

Provare a utilizzare inheritance_column, quindi digitare non saranno più riservati:

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 
+10

self.inheritance_column = nil funziona senza il simbolo – DDDD

+0

grazie per l'informazione @DDDD! –

+0

I get 'Il meccanismo di ereditarietà a tavolo singolo non è riuscito a localizzare la sottoclasse 'service'' quando si esegue questa operazione –

7

Proprio imbattuto in questo post durante il tentativo di trovare una soluzione al mio problema con questa parola type riserva quindi forse questo può aiutare qualcun altro.

Cambiare il nome della colonna non è una soluzione facile per me perché sto lavorando su un sistema completo esistente che passa alla registrazione attiva da mongodb.

Ho trovato l'aggiunta di self.inheritance_column = :_type_disabled al modello con il nome della colonna incriminato risolto l'errore che ho trovato here.

So che non stiamo usando alcuna ereditarietà quindi penso che sia giusto per me farlo ma non so quali altre implicazioni potrebbero esserci a causa di ciò. Se qualcun altro ha qualche opinione su questo sarei interessato a sapere.

Se si può semplicemente modificare il nome della colonna ed evitare di farlo, questa è una soluzione molto migliore, ne sono sicuro.

0

Se hai trovato questa domanda perché hai riscontrato lo stesso errore e utilizzi Rails STI, ma hai ricevuto l'errore perché stavi cercando di rinominare le sottoclassi ereditate, è probabile che tu abbia vecchi dati nella colonna type e Ho dimenticato di aggiornarlo. Poi questo compito rake potrebbe aiutare:

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