2009-09-02 72 views
1

我有一個Map模型,它定義了MUD中給定區域的ASCII-art地圖的細節。我希望能夠使用它的名稱而不是其ID來訪問每個地圖的頁面,所以如果我有西部地區的地圖,我希望能夠從/maps/western_ithmia(還有/maps/withmia)訪問它。需要同時創建兩個相關的Rails模型

我有第二個模型,MapAlias,其中包含可用於路徑到達地圖的所有現有短名稱。外鍵與每個別名一起存儲,指的是其關聯的Map的ID。

我想要做的是與每個新創建的Map同時創建一個新的MapAlias。不幸的是,它似乎沒有得到我的新的Map的ID直到它被保存,但我不想保存它,直到我已驗證/保存其新的MapAlias。更糟糕的是,我希望每個Map都知道哪個MapAlias是其主要別名,即生成鏈接將引用哪個。這似乎是一個循環依賴於我...

我還是很新的Rails,所以我不知道我應該做什麼,但我已經探討了模型回調鉤子(像before_save)只有限的成功 - 我仍然有處理循環依賴。有任何想法嗎? =/

回答

0

好了,時間公平一點後,我想我有一個工作解決方案。當我寫這個問題時,Map has_many MapAlias'es,每個MapAlias都屬於一個Map。我最近意識到我想要的是另一個關聯:一個地圖屬於它的主要名稱,該網站在該地圖的鏈接中使用該名稱。我添加了三個鉤子 - 兩個用於設置/創建別名的before_validation_on_ *,一個用於爲原始關聯設置別名的map_id外鍵的after_create - 並且它就像一個魅力一樣。

對於控制器它只是一個地圖。保存通話,但在內部,別名首先保存:

belongs_to :shortname, :class_name => "MapAlias" # primary name 

before_validation_on_create :add_map_alias 
def add_map_alias 
    self.create_shortname(:title => self.title) 

    @alias_failed = !(self.shortname.errors.empty?) 

    nil 
end 

before_validation_on_update :set_map_alias 
def set_map_alias 
    self.shortname.title = self.title 
    self.shortname.save(false) 

    @alias_failed = !(self.shortname.errors.empty?) 

    nil 
end 

after_create :set_alias_map_id 
def set_alias_map_id 
    self.shortname.update_attribute :map_id, self.id 

    nil 
end 

它可能不是最理想的解決方案,但它工作得很好,我的目的。感謝大家的建議,無論如何!

1

總結這一切在一個數據庫事務:

Map.transaction do 
    # ... save all your stuff ... 
end 

不要試圖重新實現與回調的交易......讓數據庫做它擅長。它會全部得到保存,否則它們都不會被保存。

0

我通常做的是手動同時創建兩個模型。也就是說,如果我有兩個模型,原因和效果,那麼我創建了我可以創建一個原因(通常來自控制器)的所有方法,並且包含一條線,如果原因已創建,則會創建一個效果,傳入這樣,即使沒有保存,我也可以訪問它的ID(因爲對象仍然存在於方法中,即使它沒有保存)。

它可能不像before_save方法那樣自動,但我喜歡能夠看到會發生什麼,以及何時,在方法之前/之後沒有生根。

0

如果您試圖通過html表單進行操作,可以在控制器上的新Map實例上調用build


# maps_controller.rb 
def new 
    @map = Map.new 
    @map_alias = @map.map_aliases.build 
end 

還有更多了一點(創建虛擬屬性),但你可以看看這個截屏的一些想法: http://railscasts.com/episodes/75-complex-forms-part-3

相關問題