5

w mojej bazy danych mam tabeli people i używam pojedynczej tabeli dziedziczenia, z tych klas:Szyny STI i wielopoziomowe dziedziczenie odpytuje

class Person < ActiveRecord::Base 
end 

class Member < Person 
end 

class Business < Member 
end 

Demonstration of the problem

Zapytania to generuje mylić mnie. Chcę, aby Member.all zwrócił wszystkie firmy, a także inne podtypy członków. Który to robi, ale tylko wtedy, gdy ostatnio uzyskałem dostęp do klasy Business. Zakładam, że dzieje się tak, ponieważ moje klasy nie są buforowane w trybie programistycznym (z oczywistych powodów), ale nadal wydaje się dziwne/błędne zachowanie.

Czy to błąd w szynach? Czy to działa zgodnie z przeznaczeniem? W obu przypadkach, czy ktoś może pomyśleć o dobrej poprawce do celów programistycznych?

+0

proszę określić rodzaje dziedziczenia w każdej klasie. –

+0

Co masz na myśli, huan synu? – Obversity

Odpowiedz

1

Jest to celowe zachowanie-oficjalny przewodnik Szyny na Autoloading and Reloading Constants wyjaśnia to całkiem dobrze w części dotyczącej Autoloading and STI:

...

Sposób zapewnienia tego działa ctly niezależnie od kolejności wykonanie jest załadowanie liści drzewa ręcznie na dole pliku, który określa klasę root:

# app/models/polygon.rb 
class Polygon < ApplicationRecord 
end 
require_dependency 'square' 

tylko liście, które są co najmniej wnuki muszą być ładowane ten sposób . Bezpośrednie podklasy nie muszą być wstępnie ładowane. Jeśli hierarchia jest głębsza, klasy pośrednie będą automatycznie ładowane rekurencyjnie od na dole, ponieważ ich stała pojawi się w definicjach klas jako nadklasa.

W twoim przypadku oznacza to umieszczenie require_dependency "business" na końcu klasy Osoby.

Jednak strzeż się wzajemnie od siebie zależnych, które mogą być ewentualnie uniknąć stosując require zamiast require_dependency (choć może zakazać Rails śledzenie i przeładowywania plików po wprowadzeniu zmian, po wszystkim, require_dependency to metoda Szyny wewnętrzne) .

+0

To interesujące rozwiązanie. Spróbuję, że następnym razem to się pojawi! – Obversity

3

Domyślnie Rails nie jest chętny do wczytywania twoich klas w rozwój. Spróbuj zmienić następującą linię w config/environments/development.rb:

# Do not eager load code on boot. 
config.eager_load = false 

do:

# Do eager load code on boot! 
config.eager_load = true 
+0

Ładna myśl! Wygląda na to, że działałem w fałszywej aplikacji, którą zrobiłem, aby replikować problem, ale nie naprawiłem wszystkich moich problemów w mojej prawdziwej aplikacji (co mogło być spowodowane innymi rzeczami). Będę oznaczać jako zaakceptowany później, kiedy będę miał czas na sprawdzenie. Dzięki! – Obversity