2014-01-24 39 views
0

我很爲難嘗試建模的自我指涉的,多到多,對稱實體使用的DataMapper:自我指涉的對稱多到許多

我想跟蹤各種軟件版本的兼容性我要追蹤:

class SoftwareRelease 
    include DataMapper::Resource 

    property :id, Serial 
    property :software_release_type_id, Integer 
    property :version, String 

    belongs_to :software_release_type 
    has n, :compatibilities, child_key: [ :source_id ] 
    has n, :compatible_releases, self, through: :compatibilities, via: :target 
end 

class SoftwareReleaseType 
    include DataMapper::Resource 

    property :id, Serial 
    property :name, String 
    property :short_name, String 

    has n, :software_releases 
end 

class Compatibility 
    include DataMapper::Resource 

    belongs_to :source, 'SoftwareRelease', key: true 
    belongs_to :target, 'SoftwareRelease', key: true 
end 

一個給定的軟件版本「ABC」可以有一個類型的硬件洗車臺富'的,而給定的軟件版本「高清」可以有一個類型的硬件平臺吧'的。

要在上面的代碼建立兼容的軟件版本之間,我必須執行2增加了

release_a_b_c.compatible_releases << release_d_e_f 
release_d_e_f.compatible_releases << release_a_b_c 

這有點兒難看。

我希望能夠做一個添加並建立對稱關係。我明顯可以用SoftwareRelease中的一個實例方法包裝2推,但感覺就像我在地毯下掃視醜陋。任何想法爲優雅的解決方案?

非常感激,

帕維爾

PS

很久以前,主動記錄有acts_as_network插件,它沒有類似的東西。無法在DM世界找到任何東西。

回答

0

我不認爲在DM或其插件中有什麼可以做你想做的事情,但我想假設編寫一個實例方法來創建單向關係實際上是相當優雅的,而我根本不會認爲它是「在地毯下掃清醜陋」。

在類中實現對象關係的部分功能是程序員通過在類中創建實例方法來以有意義的方式擴展這些類。你需要對象之間的對稱關係,所以編寫簡單的實例方法是有意義的並且是自我記錄的。並且不存在副作用或不適當調用的風險,因爲它是該特定類的公共方法。

我並沒有真正說新的東西,在這裏,但我認爲你的解決方案是完全可以接受的。坦率地說,我寧願將相對罕見的用例推入程序員的領域,而不是混淆DataMapper代碼。我不需要那些大型的Victorinox小刀和其他各種可以想象的工具。 :)