修改:根据评论中的建议更新了问题以显示我对:child_key => [:comparison_id]
的使用情况。
我有两个看起来像这样的模型:
class Comparison
include DataMapper::Resource
property :id, Serial
end
class Msrun
include DataMapper::Resource
property :id, Serial
property :name, String
end
比较来自比较两组Msruns。我以为我会通过Comparison和Msrun之间的两个多对多关系代表这一点,但是我在如何在DataMapper中做到这一点时,我正在打击我的脑袋。我知道通过添加以下内容可以获得多对多关系:
has n, :whatevers, :through => Resource
然而,这只会在两个模型之间建立一对多的关系。我还尝试创建两个连接模型并手动指定关系,并为每个关系手动指定子键,如下所示:
# Join model for the comparison-msrun many-to-many relationship.
class First
include DataMapper::Resource
belongs_to :msrun, :key => true
belongs_to :comparison, :key => true
end
# Join model for the comparison-msrun many-to-many relationship.
class Second
include DataMapper::Resource
belongs_to :msrun, :key => true
belongs_to :comparison, :key => true
end
class Comparison
include DataMapper::Resource
property :id, Serial
has n, :firsts
has n, :msrun_firsts, 'Msrun', :through => :firsts, :child_key => [:msrun_id]
has n, :seconds
has n, :msruns_seconds, 'Msrun', :through => :seconds, :child_key => [:msrun_id]
end
class Msrun
include DataMapper::Resource
property :id, Serial
property :name, String
has n, :firsts
has n, :comparison_firsts, 'Comparison', :through => :firsts, :child_key => [:comparison_id]
has n, :seconds
has n, :comparison_seconds, 'Comparison', :through => :seconds, :child_key => [:comparison_id]
end
运行automigrate
会导致以下错误:
rake aborted!
No relationships named msrun_firsts or msrun_first in First
我在这里做错了什么?我怎样才能做到这一点?
答案 0 :(得分:0)
根据DataMapper docs
我相信你可以做到:
class Msrun
include DataMapper::Resource
property :id, Serial
property :name, String
has n, :firsts #This line could probably be omitted
has n, :first_comparisons, 'Comparison', :through => :firsts
has n, :seconds #This line could probably be omitted
has n, :second_comparisons, 'Comparison', :through => :seconds
end
答案 1 :(得分:0)
您所观察到的是,关系存储在一个类似于对象的集合中,更具体地说,是一个使用关系名称作为鉴别器的集合。那么在你的情况下会发生的是,后一个定义会覆盖前者,因为集合不允许重复的条目(在我们的例子中,为了集合的目的,用较新的条目替换较旧的条目,相同的条目)。
这有实际的原因。在一个模型上声明两个所谓的不同关系是没有意义的,但是将它们命名为相同。在尝试访问它们时,您如何区分它们?这体现在DM的实现中,其中由关系名称命名的方法在Resource上定义。因此,在您尝试向集合添加副本的情况下,DM最终会做的是,它将仅使用后面的选项来生成该方法的实现。即使它接受重复的关系名称,后一种关系也会导致相同方法的覆盖/重新定义版本,从而使您具有相同的净效果。
因此,您需要在模型上定义不同名称的关系。当你考虑它时,它真的很有意义。为了帮助DM推断要使用的模型,您可以将模型名称(或常量本身)作为第3个参数传递给has
方法,或者作为belongs_to
class Comparison
include DataMapper::Resource
property :id, Serial
has n, :firsts
has n, :first_msruns, 'Msrun', :through => :firsts
has n, :seconds
has n, :second_msruns, 'Msrun', :through => :seconds
end
class Msrun
include DataMapper::Resource
property :id, Serial
property :name, String
has n, :firsts
has n, :first_comparisons, 'Comparison', :through => :firsts
has n, :seconds
has n, :second_comparisons, 'Comparison', :through => :seconds
end
希望有所帮助!