Czy jest jakiś sposób w sytuacji RI w STI, aby wygenerować błąd podczas tworzenia klasy bazowej? Zastąpienie inicjalizacji zrobi to, ale wtedy to spływa do podklas.Railsy STI - Zapobiegaj klasie bazowej z instancją
Dzięki
Czy jest jakiś sposób w sytuacji RI w STI, aby wygenerować błąd podczas tworzenia klasy bazowej? Zastąpienie inicjalizacji zrobi to, ale wtedy to spływa do podklas.Railsy STI - Zapobiegaj klasie bazowej z instancją
Dzięki
W kontroli działania initialize, że klasa jest klasą bazową STI.
Chociaż pytanie brzmi, dlaczego dokładnie chcesz to zrobić? Wydaje się bardziej prawdopodobne, że wypróbowanie innego projektu może ci pomóc.
Możesz zrobić self.abstract_class = true
w klasie bazowej, aby powiedzieć ActiveRecord, że jest to klasa abstrakcyjna.
Można spróbować to:
class BaseClass
def initialize
raise "BaseClass cannot be initialized" if self.class == BaseClass
end
end
class ChildClass
end
wynik będzie:
a = BaseClass.new # Runtime Error
b = ChildClass.new # Ok
nadzieję, że pomoże
Odpowiedź Johna Topley jest rzeczywiście źle. Ustawienie klasy abstract_class = true w klasie bazowej spowoduje, że klasy potomne przestaną automatycznie ustawiać typ. Dodatkowo, jeśli nie ustawisz set_table_name w klasie bazowej, klasy dzieci będą narzekać, że ich tabela nie istnieje.
Dzieje się tak, ponieważ celem klasy abstract_class = true jest ustawienie dziedziczenia, gdy NIE używasz STI, i chcesz mieć klasę abstrakcyjną (klasa nieobsługiwana przez tabelę db) w hierarchii klas między ActiveRecord :: Base i jedną lub więcej klas modeli.
Po inicjowaniu podniesienia jest jednym rozwiązaniem, również dodanie validates_presence_of: type do klasy bazowej jest rozwiązaniem.
Uwaga Jeśli nie zastępują initialize, trzeba zadzwonić Super:
def initialize(*args)
raise "Cannot directly instantiate an AbstractUser" if self.class == AbstractUser
super
end
Dlaczego ta odpowiedź nie jest u góry odpowiedzi? Znajduje się poniżej odpowiedzi z 0 głosów i drugą, która została usunięta. –
często wolą po prostu sprawiają, że metoda new
klasa prywatny z:
class Base
private_class_method :new
end
ten sposób przypadkowego instancji z Klasa podstawowa uruchamia błąd, ale nadal można utworzyć instancję za pomocą Base.send(:new)
, aby pisać testy dla klasy Base.
Ponieważ klasa BaseClass prawdopodobnie będzie pochodzić z ActiveRecord :: Base, inicjalizacja powinna prawdopodobnie wywołać super. – Douglas