2012-11-09 41 views
9

我有一個has_many和has_many的模型:通過模型關係。舉例來說,在我的User類我有:檢測r​​ails中的更改has_many:通過關係

的has_many:語文,通過:profile_languages

我想什麼是能夠檢測到這些時,添加或刪除使用「User.changes」功能,它返回一個用User.language_ids = function調用的屬性數組。

有沒有其他人試圖做到這一點,或有這方面的經驗?在加載ActiveModel

信息功能的變化:http://api.rubyonrails.org/classes/ActiveModel/Dirty.html

編輯:按照要求,這裏是我在做什麼。

在分配用戶屬性並保存之前,我正在查看.changes返回的所有值,以便記錄外部日誌中所做的所有更改。

所以,如果我叫u.name = 「新名稱」

然後u.changes返回{名稱: '老字號', '新名']}

然而,當我通過用戶一堆語言ID,如

u.language_ids = [4,5]

然後有許多創建ProfileLanguage模型,並且u.changes散列留空。

我試圖在ProfileLanguage模型中創建一些回調,手動創建某種散列,但我想知道這是否確實是最好的解決方案。

+0

嗨羅恩,你可以請你更具體一點關於你的問題?也許向我們展示你到目前爲止所做的設置,以便我們有一些事情可以解決。 – Noz

+0

你看過回調或觀察者嗎? – Ari

+0

添加了編輯。希望它可以澄清 –

回答

10

我有點骯髒的解決方案,我用現在去是回調添加到的has_many功能:

has_many :languages, through: :profile_languages, 
     :after_add => :language_add, 
     :before_remove => :language_remove 

並添加此信息,以自定義的哈希,將在當我是一個配置文件的保存檢查看着.changes功能。

+0

這不適合我。看起來,after_add和before_remove回調不會在您執行批量分配時觸發(就像op與language_ids一樣)。難道我做錯了什麼? – morgler

+0

它的工作原理是,這些回調然後分別爲每個移除對象調用。 –

0

我有同樣的問題,我試圖檢查更新模型時是否創建或刪除了新的關係。

我試過使用model.relationship.any? { |a| a.changed? }但這隻能檢測到已存在的對象的變化,所以它沒有用於創建和刪除關係。

尋找解決的辦法,我發現這解決了我們的問題很簡短的文章:link

使用model.select { |a| a.new_record? || e.marked_for_destruction? }.any?我已經能夠得到正在創建或銷燬所有記錄。

將此與a.changed?相結合,我可以獲得我的關係中的每一個變化。

+0

與'accep_nested_attributes_for'一起使用,但不是一般。 – maxhs

0

我知道您正在尋找實施基於文本的更改日誌,但我建議您通過paper_trail gem作爲實現您想要的方法來查看完整對象版本。它提供了this functionality according to their README

PaperTrail可以恢復三種類型的關聯:Has-One,Has-Many和Has-Many-Through。爲了做到這一點,您需要創建一個version_associations表,可以在安裝時使用rails生成paper_trail:install --with-associations選項或手動創建。 Paper Trail將在該表中存儲附加信息,以便在相關記錄更改時關聯模型的關聯版本和版本。

我沒有使用過的paper_trail的具有一對多式功能,但我已經用它的對象,而不協會,並發現它優良且易於實現。

要創建文本文件日誌以及此數據庫文件路徑,您可以在after_save回調中使用paper_trail's diff features