ruby datamapper-对称自引用多对多关系

ruby datamapper-对称自引用多对多关系,ruby,database-design,orm,ruby-datamapper,Ruby,Database Design,Orm,Ruby Datamapper,我不是数据库和关系逻辑方面的专家,我对在以下情况下必须做什么感到有点困惑 我有一个模型表达式,我想在其中实现一个TranslationPair自引用多对多关系 class Expression include DataMapper::Resource has n, :translation_pairs, child_key: [:exp_1_id] end class TranslationPair include DataMapper::Resource belongs_

我不是数据库和关系逻辑方面的专家,我对在以下情况下必须做什么感到有点困惑

我有一个模型
表达式
,我想在其中实现一个
TranslationPair
自引用多对多关系

class Expression
  include DataMapper::Resource

  has n, :translation_pairs, child_key: [:exp_1_id]
end

class TranslationPair
  include DataMapper::Resource

  belongs_to :exp_1, 'Expression', key: true
  belongs_to :exp_2, 'Expression', key: true
end
问题是,我希望
translation\u pairs
关系不仅返回
exp\u 1
字段中具有给定表达式的
translationpairs
实例,还返回
exp\u 2
字段中具有给定表达式的
translationpairs
实例(如果
expression1
expression2
的翻译,那么
expression2
expression1
的翻译)。在
child\u key
选项中有一种析取。类似于:

has n, :translation_pairs, child_key: [:exp_1_id] or [:exp_2_id]
has n, :these_translations, :model => TranslationPair, :child_key => [:exp_1]
has n, :those_translations, :model => TranslationPair, :child_key => [:exp_2]

def translation_pairs
  these_translations + those_translations
end
我可以直接在模型声明中实现它,还是必须实现一些自定义方法?

有趣的问题

仅使用DataMapper核心方法无法做到这一点。我现在只是在猜测数据的性质……但我很好奇,您是否能够为任何给定的
表达式
找到一个“规范”表示形式,使其看起来像:

class Expression
  belongs_to :canonical_translation
  ...

  def equivalent_expressions
    canonical_translation.expressions.all(:id.not => self.id)
  end
end

class CanonicalTranslation
  property :representation, SomeDataType
  has n :expressions
end
如果没有,则可能会强制您在Expression对象上使用自定义方法,例如:

has n, :translation_pairs, child_key: [:exp_1_id] or [:exp_2_id]
has n, :these_translations, :model => TranslationPair, :child_key => [:exp_1]
has n, :those_translations, :model => TranslationPair, :child_key => [:exp_2]

def translation_pairs
  these_translations + those_translations
end
有趣的问题

仅使用DataMapper核心方法无法做到这一点。我现在只是在猜测数据的性质……但我很好奇,您是否能够为任何给定的
表达式
找到一个“规范”表示形式,使其看起来像:

class Expression
  belongs_to :canonical_translation
  ...

  def equivalent_expressions
    canonical_translation.expressions.all(:id.not => self.id)
  end
end

class CanonicalTranslation
  property :representation, SomeDataType
  has n :expressions
end
如果没有,则可能会强制您在Expression对象上使用自定义方法,例如:

has n, :translation_pairs, child_key: [:exp_1_id] or [:exp_2_id]
has n, :these_translations, :model => TranslationPair, :child_key => [:exp_1]
has n, :those_translations, :model => TranslationPair, :child_key => [:exp_2]

def translation_pairs
  these_translations + those_translations
end

谢谢@mltsy。两种选择都很有趣。第一种哲学上的选择(:)很好,但我不喜欢仅仅为了某种数据映射器限制(我不确定,但我认为我想在纯SQL模式中做的事情是可能的)而改变我的模型设计(即使不会太难)。我将尝试使用第二个,因为它在将来会更容易更改。添加
这些翻译和
这些翻译时会出现问题。它们是
DataMapper::Associations::OneToMany::Collection
,它不是从
Array
继承的,因此
+
的行为与预期的连接方式不符(该方法存在,它使用所涉及的对象属性产生了一些奇怪的事情,我无法解释)。解决方法是将它们
转换为a
。当然你失去了
收藏
功能,但我知道没有它们我也能活下去……谢谢@mltsy。两种选择都很有趣。第一个哲理性的(:)很好,但是我不喜欢仅仅为了一种数据映射器的限制(我不确定,但我认为我想在纯SQL模式中做的事情是可能的)而改变我的模型设计(即使它不会太难)。我将尝试使用第二个,因为它在将来会更容易更改。添加
这些翻译和
这些翻译时会出现问题。它们是
DataMapper::Associations::OneToMany::Collection
,它不是从
Array
继承的,因此
+
的行为与预期的连接方式不符(该方法存在,它使用所涉及的对象属性产生了一些奇怪的事情,我无法解释)。解决方法是将它们
转换为a
。当然你失去了
收藏
功能,但我知道没有它们我也能活下去。。。