2015-10-15 61 views
0

Rails 3的這個主題似乎有很多問題(和答案),但我現在要求在2015年Rails 4(或即將推出的5)。如何覆蓋關聯(has_one)getter(延遲加載)?

我試圖使用圖案像以下的(用於在用戶::資料的情況下的HAS_ONE協會,我想懶惰負荷):

def profile 
    self.build_profile unless self[:profile] 
    super 
end 

的問題是,在上述端部使用一個沒有.id的Profile對象,所以表格只會附加無關聯的記錄。

這工作(但我打電話超兩次,我不知道有足夠的瞭解紅寶石知道這是一件可怕的事情 - 沒有任何警告):

def profile 
    self.build_profile unless super 
    super 
end 

活動記錄文檔顯示你可以使用super或* _attribute(或[]),但是在實現'超級'的過程中,關聯關係似乎有所不同。

我仍然可以使用別名方法鏈接,但我想知道我的模式有什麼問題。

編輯:看來使用「accep_nested_attributes_for」使這件事情變得複雜。

+0

我刪除了overidden getter和將我的'fields_for'改爲包含創建佔位符對象的簡單邏輯,例如:<%= f.fields_for:profile,(user.profile || user.build_profile)do | profile_f | %>這不是我的問題的答案,但它是我提出的問題的完全可以接受的解決方案。 – chrisp

回答

2

你的第一個例子沒有id​​的原因是因爲build_profile是因爲它只實例化了一個新的Profile對象而沒有將它保存到數據庫中。如果您希望將其保存到數據庫中,則應該使用create_profile。另外,如果配置文件尚不存在,super將返回nil。試試這個簡單的方法:

def profile 
    super || self.create_profile 
end 

有關附帶一個has_one關聯的輔助方法的詳細信息,請參閱Rails的文檔的第4.2.1節:

http://guides.rubyonrails.org/association_basics.html#has-one-association-reference

+0

你能解釋爲什麼第二種方法可行嗎? – chrisp

+0

嗯,我不知道你在調用這個方法的上下文是什麼,所以我不確定什麼是合格的工作解決方案。糾正我,如果我錯了我相信,但你提出的兩種方法將返回一個新的'配置文件'對象沒有一個id(就像'Profile.new'),除非已經存在數據庫中的關聯配置文件。 –

+0

顯示的第二種方法最終以有效記錄保存到商店(使用ID)。實施中沒有其他區別。 – chrisp