2009-12-01 8 views
5

Zacząłem się uczyć Datamapper i podobało mi się to, że mogę pisać moje modele z prawdziwym dziedzictwem.Ruby Datamapper dziedziczenie tabeli ze stowarzyszeniami

Teraz zastanawiam się, czy jest możliwe, aby być bardziej zaawansowana na ten temat:

class Event 
    include DataMapper::Resource 
    property :id, Serial 
    property :begin, DateTime 
    property :type, Discriminator 
end 

class Talk<Event 
    property :title, String 
    belongs_to :meeting 
end 

class Meeting<Event 
    has n, :talks 
end 

Ten kod nie powiedzie się, aby utworzyć kolumnę :title dla Talk i oczywiście kolumna dyskryminator ma niewielką wartość tutaj, ponieważ z widoku bazy danych powinny być oddzielne tabele dla obu Talk i Meeting.

Więc w końcu, chcę Talk i Meeting dzielić te same właściwości, jak zdefiniowano w Event ale z ewentualnymi dodatkowymi właściwościami iz 0..1: n relacja (spotkanie może mieć kilka rozmów, ale są rozmowy bez spotkania.) Czy istnieje sposób, aby to osiągnąć bez powtarzania definicji kolumn i/lub porzucania dziedziczenia?

Edit

Aby podać inny przykład: część, która podoba mi się rzeczą dziedziczenie jest, że ogólne Event s można przeszukiwać osobno. Tak więc, kiedy chcę wiedzieć, czy jest coś na pewną datę :begin, nie muszę szukać w dwóch lub więcej tabelach, ale mogę po prostu zapytać o tabelę Event. W pewnym sensie następująca struktura mogłaby pasować do moich potrzeb.

class Event 
    include DataMapper::Resource 
    property :id, Serial 
    property :begin, DateTime 
end 

class Talk 
    include DataMapper::Resource 
    property :id, Serial 
    property :title, String 
    belongs_to :event 
    belongs_to :meeting 
end 

class Meeting 
    include DataMapper::Resource 
    property :id, Serial 
    belongs_to :event 
    has n, :talks 
end 

Jednak aby wykorzystać to, że muszę ręcznie utworzyć an Event za każdym razem, chcę utworzyć lub edytować Talk. Oznacza to, że nie mogę wykonać talk.begin ani Talk.create(:begin => Time.now). Czy istnieje sposób obejścia tego bez poprawiania wszystkich funkcji i łączenia właściwości? Nie chcę otrzymywać przypomnień o podstawowej strukturze podczas korzystania z modelu.

+0

Jaki dziedziczenie masz na myśli przez realne dziedziczenie - Dziedziczenie z pojedynczej tabeli, Dziedziczenie z tabeli klas lub Dziedziczenie z tablicy betonowej? http://martinfowler.com/eaaCatalog/ – MattMcKnight

+0

Mam na myśli dziedziczenie klasy Ruby. – Debilski

+0

Niezależnie od tego, co oznacza to tabelarycznie, nie przejmuję się tym zbytnio - dopóki mogę używać każdego modelu Ruby osobno i rzucać/przypisać z podklasy rodzicowi iz powrotem. – Debilski

Odpowiedz

8

Jeśli chcesz replikować atrybuty imprezy język Talk i zgromadzenia, a następnie można go przenieść do modułu:

module EventFields 
    def self.included(base) 
    base.class_eval do 
     include DataMapper::Resource 
     property :id, DataMapper::Types::Serial 
     property :begin, DateTime 
     # other fields here 
    end 
    end 
end 

class Talk 
    include EventFields 
    property :title, String 
    belongs_to :meeting 
end 

class Meeting 
    include EventFields 
    has n, :talks 
end 

To daje różne tabele ale oznacza powielanie jest zmniejszona.

+0

Ale to niestety oznacza, że ​​nie ma przejrzystego sposobu na odpytywanie wszystkich zdarzeń w tym samym czasie, więc musiałbym duplikować dla wszystkich typów zdarzeń. – Debilski

+0

Prawda, ale dziedziczenie pojedynczej tabeli jest odpowiednie tylko dla obiektów, które zachowują się inaczej, ale mają tę samą podstawową strukturę/tabelę. Musisz odnieść hołd przechowywania wszystkich atrybutów (na przykład w klasie Event) i budowania logiki dla relacji wewnątrz każdej klasy dziecka. Niestety, STI sugeruje, że istnieje pewne magiczne rozwiązanie elastyczne, ale rzadko tak jest. W miarę rozrastania się modeli stają się zbyt ciasno powiązane, a STI nie będzie już miało sensu. – JamesAlmond

+0

Masz rację, i tak będę musiał pójść na taki kompromis. Mamy nadzieję, że w pewnym momencie DataMapper :: EmbeddedValue będzie dostępna, aby ułatwić Twoją sugestię. – Debilski

Powiązane problemy