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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With