带有关联的Ruby Datamapper表继承 [英] Ruby Datamapper table inheritance with associations

查看:87
本文介绍了带有关联的Ruby Datamapper表继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始学习 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

该代码无法为Talk创建:title列,显然,discriminator列在这里价值不大,因为从数据库视图来看,TalkMeeting都应该有单独的表

因此,最后,我希望TalkMeeting共享与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

但是,要使用此功能,每次要创建或编辑Talk时,我都需要手动创建Event.也就是说,我不能执行talk.beginTalk.create(:begin => Time.now).是否有解决此问题的方法而不修补所有功能并合并属性?使用该模型时,我不希望被提醒其底层结构.

解决方案

如果要将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

这将为您提供不同的表,但意味着减少重复.

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.

这篇关于带有关联的Ruby Datamapper表继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆