2009-12-01 11 views
5

Datamapper'u öğrenmeye başladım ve bu konuda sevdiğim şey, modellerini gerçek miras ile yazabilmem idi.Ruby Datamapper tablosu ilişkilendirmeleri ile ilişkilendirmeler

Bu kod Açıkçası Talk ve için :title sütun oluşturun başarısız
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 

, ayırt edici sütun burada az bir değer taşır, çünkü: konu hakkında daha ileri olması mümkün olup olmadığını

Şimdi ben merak Bir veritabanı görünümünden, hem Talk hem de Meeting için ayrı tablolar olmalıdır.

Yani, sonunda, ben Event ama muhtemel ek özelliklere sahip ve bir 0..1 ile tanımlanan aynı özelliklere paylaşmak için Talk ve Meeting istiyorum: n ilişkisi (Bir toplantı çeşitli temaslarda olabilir ama görüşmeler var Bir toplantı olmadan.) Kolon tanımlarını tekrarlamadan ve/veya mirastan vazgeçmeden bunu başarmanın bir yolu var mı?

başka örnek vermek gerekirse Düzenleme: miras şey genel Event ler ayrı ayrı sorgulanabilir yani, hakkında gibi parçasını. Yani, bilmek istediğimde, belirli bir :begin tarihinde bir şey varsa, iki veya daha fazla tabloya bakmam gerekmiyor ancak Event tablosunu sorgulayabilirim. Bir şekilde, aşağıdaki yapı benim ihtiyaçlarına uyabiliyordu.

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 

Ancak bu kullanmak için, ben oluşturmak veya Talk düzenlemek istediğiniz, el ile Event her zaman yaratmak gerekir. Yani, talk.begin veya Talk.create(:begin => Time.now) yapamıyorum. Tüm fonksiyonları yatırmadan ve özellikleri birleştirmeden bunun etrafında bir yolu var mı? Modeli kullanırken temel yapıyı hatırlatmak istemiyorum.

+0

Gerçek miras yoluyla hangi kalıtım türünü kastediyorsunuz? Tek Tablo Kalıtım, Sınıf Tablosu Kalıtım veya Beton Tablo Kalıtım? http://martinfowler.com/eaaCatalog/ – MattMcKnight

+0

Ruby sınıfının mirasını kastediyorum. – Debilski

+0

Bu ne anlama geliyorsa bilmiyorum, her Ruby modelini ayrı ayrı kullanabildiğim ve alt sınıftan ana ve arkaya atama/atayabildiğim kadarıyla - bu kadar ilgilenmiyorum. – Debilski

cevap

8

Eğer Talk ve Toplantı içine Olay özelliklerini çoğaltmak istiyorsanız o zaman bir modül içine taşımak olabilir:

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 

Bu, size farklı tablolar vermek ama çoğaltılması azalacak demektir olacaktır.

+0

Ancak bu, maalesef, tüm Olayları aynı anda sorgulamanın saydam bir yolu olmadığı için, her tür etkinlik için kopyalamak zorunda kalacağım. – Debilski

+0

Doğru, ancak tek tablo devralma yalnızca farklı davranan ancak aynı alt yapıya/tabloya sahip olan nesneler için makul olarak uygundur. Tüm niteliklerin (örneğin, Event sınıfında) saklanması ve her alt sınıftaki ilişkilerin mantığının oluşturulması adımını atmanız gerekir. Ne yazık ki, STI bazı sihirli esnek veri çözümü olduğunu öne sürüyor, ancak nadiren durum böyle. Modeller büyüdükçe çok sıkı bir şekilde birleşecekler ve STI artık daha fazla mantıklı olmayacak. – JamesAlmond

+0

Haklısın, böyle yapılarda bir uzlaşma yapmak zorunda kalacağım. Umarım, bir noktada, önerinizi kolaylaştırmak için DataMapper :: EmbeddedValue mevcut olacaktır. – Debilski

İlgili konular