2013-07-26 9 views
29

Jestem początkującym użytkownikiem Rails.
mam dwa modele Kategoria i produktu w następujący sposób: -ActiveRecord :: SubclassNotFound: mechanizm dziedziczenia pojedynczego zbioru nie zdołał zlokalizować podklasy

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 

A moja schema.rb przedstawia się następująco: -

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 

W konsoli Rails Stworzyłem dwa produkty z dwoma produktami za pomocą Product.create polecenie

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

i stworzył dwie kategorie ze polecenia Category.create w konsoli

<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"> 

Teraz Product.all działa dobrze, ale Category.all daje

ActiveRecord :: SubclassNotFound: mechanizm dziedziczenia pojedynczego zbioru nie zdołał zlokalizować podklasy: "ubranie". Ten błąd został zgłoszony, ponieważ kolumna "typ" jest zarezerwowana do przechowywania klasy w przypadku dziedziczenia. Zmień nazwę tej kolumny, jeśli nie zamierzasz jej użyć do przechowywania klasy dziedziczenia lub zastąpienia kolumny Category.inheritance_column, aby użyć innej kolumny dla tej informacji.

Co jest nie tak? Chcę utworzyć relację między kategorią a produktem, np.
kategoria has_many produkty i produkty należą do kategorii.

Odpowiedz

72

type jest słowem ograniczonym, nie można go używać jako nazwy kolumny w modelach ActiveRecord (chyba że robisz STI).

+0

Dzięki. Teraz zmieniłem "typ" na "nazwa". ale kiedy robię kategorię = Category.first, a następnie "category.products" pokazuje tylko produkt o id = 1.it powinien pokazywać wszystkie produkty w tej kategorii. – mrudult

+0

'Category.first.products' zawsze zwróci (tablica - dla uproszczenia, ponieważ nie pamiętam dokładnej nazwy typu) wszystkie produkty powiązane z tą kategorią. –

+0

Yup miał literówkę. To działa dobrze. – mrudult

2

Jeśli ktokolwiek próbuje pobrać STI, spróbuj dodać nową klasę dziedziczącą po rodzicu, a komunikat o błędzie powinien zniknąć.

class YourSubclass < Category 
end 
17

Spróbuj użyć inheritance_column, a następnie wpisz nie będą już zarezerwowane:

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 = zero działa bez symbolu – DDDD

+0

dzięki za informacje @DDDD! –

+0

Otrzymuję 'Mechanizm dziedziczenia jednokolumnowego nie udało się zlokalizować podklasy 'usługi'' podczas wykonywania tego –

7

Właśnie natknąłem tego postu, starając się znaleźć rozwiązanie do mojego problemu z tym type rezerwowej słowa, więc może to możliwe pomóżcie komuś innemu.

Zmiana nazwy kolumny nie jest dla mnie łatwym rozwiązaniem, ponieważ pracuję nad istniejącym kompletnym systemem migrującym do aktywnego rekordu z mongodb.

Znalazłem dodanie self.inheritance_column = :_type_disabled do modelu z nieprawidłową nazwą kolumny naprawiono błąd, który znalazłem here.

Wiem, że nie używamy żadnego dziedzictwa, więc myślę, że to dla mnie w porządku, ale nie wiem, jakie inne mogą być tego konsekwencje. Jeśli ktokolwiek ma jakieś zdanie na ten temat, byłbym zainteresowany.

Jeśli możesz po prostu zmienić nazwę kolumny i uniknąć tego, to jestem o wiele lepszym rozwiązaniem, jestem tego pewien.

0

Jeśli znalazłeś to pytanie, ponieważ napotkałeś ten sam błąd i używasz Rails STI, ale otrzymałeś błąd, ponieważ próbujesz zmienić nazwę dziedziczonych podklas, prawdopodobnie wynika to z tego, że masz stare dane w kolumnie type i zapomniałem go zaktualizować. Wtedy to zadanie natarcia może pomóc:

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 
Powiązane problemy