2011-06-23 64 views
0

編輯:已更新的問題顯示我使用的:child_key => [:comparison_id]正如評論中所建議的。如何在DataMapper中爲同一模型創建兩個多對多關係?

我有兩個模型,如下所示:

class Comparison 
    include DataMapper::Resource 
    property :id, Serial 
end 

class Msrun 
    include DataMapper::Resource 
    property :id, Serial 
    property :name, String 
end 

比較來自比較兩組Msruns的。我認爲我會通過比較到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

由於每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 
+0

對不起,我應該說得更清楚。我已經嘗試過了,並且出現以下錯誤:第一個沒有名爲first_msruns或first_msrun的關係 – jergason

+1

爲了避免命名錯誤,您必須爲Msrun指定'has n,:firsts,...:child_key => [:msrun_id]' ''和'具有n,:firsts,...:child_key => [:comparison_id]'用於'Comparison'。 ':child_key'需要綁定不同名稱的字段。 – ujifgc

0

什麼您看到的,是關係存儲在一組類似物體的引擎蓋下,更具體的事實,一個使用關係名稱作爲鑑別器的集合。所以在你的情況下會發生什麼,後一個定義會覆蓋前者,因爲集合不允許重複條目(在我們的例子中,爲了集合的目的,將新條目替換爲舊條目)。

這有實際的原因。在一個模型上聲明兩個假定不同的關係是沒有意義的,但是將它們命名爲相同。如何在嘗試訪問它們時區別它們?這體現在DM的實現中,其中由關係名稱命名的方法在資源上被定義。那麼,在您嘗試向該集合添加副本的情況下,DM最終要做的是僅使用後面的選項來生成該方法的實現。即使它接受重複的關係名稱,後一種關係也會導致相同方法的重寫/重新定義版本,從而使您獲得相同的淨效果。

因此,您需要在模型上定義不同名稱的關係。當你考慮它時,它確實很有意義。爲了幫助DM與推斷模型中使用的,可以作爲第三個參數傳遞的型號名稱(或常量本身)的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 

希望幫助!

+0

該代碼是否可以爲您成功工作?這給了我以下錯誤:First中沒有名爲first_msruns或first_msrun的關係。 – jergason

相關問題