Наследование таблиц Ruby Datamapper со связями - PullRequest
5 голосов
/ 02 декабря 2009

Я начал изучать Datamapper , и мне понравилось то, что я мог писать свои модели с настоящим наследованием.

Теперь мне интересно, можно ли быть более продвинутым в этом:

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

Этот код не может создать столбец :title для Talk, и, очевидно, здесь столбец дискриминатора не имеет большого значения, поскольку в представлении базы данных должны быть отдельные таблицы для Talk и Meeting. .

Итак, в конце я хочу, чтобы Talk и Meeting имели те же свойства, что определены в Event, но с возможными дополнительными свойствами и с отношением 0..1: n (Совещание может иметь несколько говорит, но есть переговоры без встречи.) Есть ли способ сделать это, не повторяя определения столбцов и / или не отказываясь от наследства?

Редактировать

Чтобы привести другой пример: часть, которая мне нравится в наследовании, состоит в том, что общие Event можно запрашивать отдельно. Поэтому, когда я хочу узнать, есть ли что-то на определенную дату :begin, мне не нужно просматривать две или более таблиц, а можно просто запросить таблицу Event. В некотором смысле, следующая структура может соответствовать моим потребностям.

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

Однако, чтобы использовать это, мне нужно было бы вручную создавать Event каждый раз, когда я хочу создать или отредактировать Talk. То есть я не могу сделать talk.begin или Talk.create(:begin => Time.now). Есть ли способ обойти это без исправления всех функций и слияния свойств? Я не хочу напоминать о базовой структуре при использовании модели.

1 Ответ

8 голосов
/ 02 декабря 2009

Если вы хотите скопировать атрибуты Event в Talk и Meeting, вы можете переместить его в модуль:

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

Это даст вам разные таблицы, но означает, что дублирование уменьшено.

...