2010-08-17 20 views
13

Aktualnie pracuję nad aplikacją Rails 3, która może wymagać użycia dziedziczenia klasy Class w kilku modelach.Dziedziczenie tabeli klas w szynach 3

Uproszczonym przykładem tego, co się dzieje, jest to.

Mam klasę o nazwie Osoba o ogólnych atrybutach takich jak nazwa, adres e-mail, hasło, które są wspólne dla wszystkich typów osób w aplikacji i używane do uwierzytelniania.

Istnieją dwie podklasy dla osoby (lub dwóch typów osób ...), kierowcy i pasażera. Obie te podklasy mają wspólne atrybuty Person, a następnie mają określone dodatkowe atrybuty, które są unikalne dla nich samych. (na przykład Kierowca może mieć wiele Pojazdów i Licencji, ale Pasażer nie chciałby)

Jak wdrożyć CTI dla tego rodzaju sytuacji? Szukałem na przykład dostarczonych tutaj:

http://rhnh.net/2010/08/15/class-table-inheritance-and-eager-loading

Ale nie spekulować na temat dostępu do wspólnych cech osoby z obiektu kierowcy lub pasażera i jestem nieco zdezorientowany że.

W szczególności, co chciałbym wiedzieć:

Jeśli mam aktualizowanie atrybuty Kierowca, w jaki sposób można łatwo uzyskać dostęp i zaktualizować odpowiednie atrybuty na stole ludzi rodzicem? Czy muszę podłączyć się do wywołania zwrotnego after_save i oddzielić aktualizację atrybutu gdzie? Czy istnieje lepszy sposób podejścia do tego?

+0

Powinienem dodać, że jest to uproszczony przykład tego, co się dzieje w mojej aplikacji. Jestem pewien, że muszę wdrożyć dziedzinę dziedziczenia klasy w mojej sytuacji, dziedziczenie z pojedynczego stołu nie byłoby najlepszym sposobem. –

+0

Dodałem komentarz do bloga, o którym wspomniałem w swoim pytaniu, a autor uprzejmie podał przykład jednego z tych sposobów: http://rhnh.net/2010/08/17/updating-class-table-inheritance- tabele (You rock Xavier!) –

Odpowiedz

5

dlaczego nie używać dziedziczenia z pojedynczej tabeli? na przykład:

class Person < ActiveRecord::Base 
    # some common code here 
end 

class Driver < Person 
    # Driver code 
end 

class Passenger < Person 
    # Passenger code 
end 

w ten sposób będziesz mieć wspólną klasy Person, plus dwa konkretne klasy pochodzące od niego

+13

Uwaga: OP zapytał o to, jak korzystać z dziedziczenia z tabeli klas, a nie z dziedziczenia z pojedynczego stołu. –

+21

Czasami ludzie pytają o niewłaściwe pytanie, właśnie odpowiedziałem na ewentualne rozwiązanie jego problemu. –

+9

Następnie należy zasugerować jako komentarz. – EdMelo

4

Używam plugin dziedziczenie tabeli klasy i to działa dobrze, http://github.com/brunofrank/class-table-inheritance

+0

Dzięki za podpowiedź, sprawdzę wtyczkę! –

+4

Nie jest to najlepsze rozwiązanie, ponieważ nie działa poprawnie z postgresami (tj. Nie używaj tego, jeśli zamierzasz używać heroku z postgres). – standup75

2

Niedawno rozwinąłem obiecujący projekt, który zaimplementował dziedziczenie wielu tabel i dziedziczenie klas w Railsach. Spędziłem kilka dni na poddaniu go szybkiemu rozwojowi, poprawkom, komentowaniu i dokumentacji i ponownie wydałem go jako CITIER (Class Inheritance and Table Inheritance Embeddings for Rails).

Myślę, że mógłbyś połączyć to z powyższymi odpowiedziami?

Rozważmy nadając mu wygląd: http://peterhamilton.github.com/citier

Spojrzałem na rozwiązaniach takich jak repo klasy tabeli spadków, ale jest to o wiele czystsze i bardziej logiczne IMO.

Obsługuje również główne języki SQL SQLite, MySQL, PostgreSQL i prawdopodobnie więcej, ale ich nie przetestowałem.

+0

Ta perła wydaje się być najbardziej kompletną z trzech funkcji. Czy mogę zapytać, czy sprawdziłeś porównanie wydajności? A także integrację z Sunspot (ponieważ używane są widoki bazy danych)? – lulalala

+0

Działa świetnie ... ale napotkaliśmy na problem z heroku. Nie podobały mu się widoki tabel, zwłaszcza podczas przesuwania/przeciągania bazy danych. Skończyło się usuwanie. – Ricky

7

Jest tam również plugin 'acts_as_relation' to zrobić,
https://github.com/hzamani/acts_as_relation/

w twoim przypadku będzie to kod:

class Driver < ActiveRecord::Base 
    acts_as :person 
end 

class Passenger < ActiveRecord::Base 
    acts_as :person 
end 

Nie zapomnij dodać person_type i person_id do kolumny persons stół.
Teraz zarówno Dysk, jak i Pasażer dziedziczą atrybuty, walidacje i metody Person.