试图从DataMapper连接表和关联中获取值

时间:2010-10-05 03:46:45

标签: ruby-on-rails-3 datamapper

我有3个类 - Mix,MixClip和Clip。

class Mix

  include DataMapper::Resource

  property :id, Serial
  # <removed other code for brevity>

  has n, :mix_clips
  has n, :clips, :through => :mix_clips

end

class MixClip
  include DataMapper::Resource

  property :id, Serial
  property :order, Integer      

  belongs_to :mix
  belongs_to :clip
end

class Clip
  include DataMapper::Resource

  property :id, Serial
  property :title,            String    
  property :description,      Text

  has n, :mix_clips
  has n, :mixes, :through => :mix_clips
end

MixClip连接Mix / Clip表,并包含一个额外的属性来描述剪辑(顺序)。我想知道是否可以有一个剪辑对象,并能够在加载的上下文中引用当前剪辑。

所以让我说我像这样加载一个Mix和一个Clip:

mix = Mix.first
clip = mix.clips.first

有没有办法获得与该特定Clip相关联的MixClip?

clip.mix_clip.order

它是通过表之间的连接加载的,所以我认为有办法实现它。

我知道我可以获得所有mix-&gt; mix-&gt;剪辑 - &gt;然后向下钻,但想知道我是否能够恢复水平......这会更简单。

对于那些想知道的人,我正在尝试使用它,因为dm-serializer在返回json / xml时并不完全支持嵌套关联,并且我希望能够只定义一个返回数据的方法。

感谢。

1 个答案:

答案 0 :(得分:2)

在不更改任何代码的情况下,您应该能够:

mix_clip = clip.mix_clips.first(:mix => mix, :clip => clip)

获取与您的特定mixclip资源相关联的加入记录。

目前,DM中存在一个错误,使得在不采取任何其他措施的情况下执行以下操作有点不可靠:

mix_clip = clip.mix_clips.get(mix.id, clip.id)

这是因为DM忘记了定义关系的顺序,因此当前无法可靠地知道.get方法应该接受主键组件的顺序。

您可以通过在连接模型中显式定义外键属性来解决此问题(请注意,您仍需要明确声明关系):

class MixClip
  include DataMapper::Resource

  property :id,      Serial
  property :order,   Integer      

  property :mix_id,  Integer, :key => true
  property :clip_id, Integer, :key => true

  belongs_to :mix
  belongs_to :clip
end

这将确保DM知道.get接受主键为(mix_id, clip_id),因此您现在可以调用

mix_clip = clip.mix_clips.get(mix.id, clip.id)

希望这样做的一个原因是,对.get的调用会考虑身份映射,根据您的访问特征,可能会产生更好的性能。