Ruby Datamapper table inheritance with associations

不羁岁月 提交于 2019-12-13 11:50:47

问题


I started learning Datamapper and what I liked about it was that I can write my models with real inheritance.

Now I wonder, if it is possible to be more advanced about this:

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

That code fails to create the :title column for the Talk and obviously, the discriminator column is of little value here, because from a database view, there should be separate tables for both Talk and Meeting.

So, in the end, I want Talk and Meeting to share the same properties as defined in Event but with possible additional properties and with a 0..1:n relation (A meeting can have several talks but there are talks without a meeting.) Is there a way to accomplish this without either repeating the column definitions and/or abandoning inheritance?

Edit

To give another example: The part that I like about the inheritance thing is, that general Events can be queried separately. So, when I want to know, if there is something at a certain :begin date, I don’t need to look in two or more tables but could just query the Event table. In a way, the following structure could fit my needs.

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

However, in order to use this, I would need to manually create an Event every time, I want to create or edit a Talk. That is, I can’t do talk.begin or Talk.create(:begin => Time.now). Is there a way around this without patching all functions and merging the properties? I don’t want to be reminded of the underlying structure when using the model.


回答1:


If you want to replicate the attributes of Event into Talk and Meeting then you could move it into a module:

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

This will give you different tables but means duplication is reduced.



来源:https://stackoverflow.com/questions/1829161/ruby-datamapper-table-inheritance-with-associations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!