问题描述
|
编辑:更新了问题,以显示我对注释中所建议的ѭ0的使用。
我有两个看起来像这样的模型:
class Comparison
include DataMapper::Resource
property :id,Serial
end
class Msrun
include DataMapper::Resource
property :id,Serial
property :name,String
end
比较来自比较两组Msruns。我以为我可以通过从Compare到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
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,:through => :seconds,:child_key => [:msrun_id]
end
class Msrun
include DataMapper::Resource
property :id,String
has n,:comparison_firsts,\'Comparison\',:child_key => [:comparison_id]
has n,:comparison_seconds,:child_key => [:comparison_id]
end
运行“ 4”会导致以下错误:
rake aborted!
No relationships named msrun_firsts or msrun_first in First
我在这里做错了什么?我该如何工作?
解决方法
您正在观察的事实是,关系存储在引擎盖下的类似对象的集合中,更具体地说,是使用关系名称作为区分符的集合。因此,在您的情况下,后一种定义会覆盖前一种,因为集合不允许重复的条目(并且在我们的案例中,出于集合的目的,将较旧的条目替换为较新的条目) 。
这有实际原因。在一个模型上声明两个假定不同的关系,但命名它们相同是没有意义的。尝试访问它们时,您将如何区分它们?这体现在DM的实现中,其中在资源上定义了由关系名称命名的方法。因此,在您尝试向集合中添加重复项的情况下,DM最终要做的是,它将仅使用后面的选项来生成该方法的实现。即使接受重复的关系名称,后一种关系也将导致同一方法的覆盖/重新定义版本,从而使您获得相同的实际效果。
结果,您将需要在模型上定义不同名称的关系。当您考虑它时,这确实有意义。为了帮助DM推断要使用的模型,您可以将模型名称(或常量本身)作为第3个参数传递给
has
方法,或作为第2个参数传递给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,:through => :seconds
end
class Msrun
include DataMapper::Resource
property :id,Serial
property :name,String
has n,:first_comparisons,\'Comparison\',:second_comparisons,:through => :seconds
end
希望有帮助!
, 根据DataMapper文档
我相信你可以做到:
class Msrun
include DataMapper::Resource
property :id,Serial
property :name,String
has n,:firsts #This line could probably be omitted
has n,:through => :firsts
has n,:seconds #This line could probably be omitted
has n,:through => :seconds
end