2010-09-17 85 views
3

我知道軌道的基本髒指標方法,如果對象的直接屬性發生了變化,我就想知道如何確定我的孩子是否已更新..Rails確定來自accept_nested_attributes_for對象的對象是否更改?

我有一個表單我們將其稱爲文件夾。文件夾accep_nested_attributes_for:文件。我需要確定(在控制器操作中)是否params散列內的文件與db中的文件不同。因此,用戶是否刪除了其中一個文件,他們是不是添加新文件,或兩者(刪除一個文件,並添加另一個)

我需要確定這一點,因爲我需要將用戶重定向到一個不同的行動,如果他們刪除了一個文件,對添加新文件,而不僅僅是文件夾的更新屬性。

回答

3
def update 
    @folder = Folder.find(params[:id]) 
    @folder.attributes = params[:folder] 

    add_new_file = false 
    delete_file = false 
    @folder.files.each do |file| 
    add_new_file = true if file.new_record? 
    delete_file = true if file.marked_for_destruction? 
    end 

    both = add_new_file && delete_file 

    if both 
    redirect_to "both_action" 
    elsif add_new_file 
    redirect_to "add_new_file_action" 
    elsif delete_file 
    redirect_to "delete_file_action" 
    else 
    redirect_to "folder_not_changed_action" 
    end 
end 

有時候你想知道該文件夾在沒有確定如何改變。在這種情況下,你可以使用autosave模式在您的關聯關係:

class Folder < ActiveRecord::Base 
    has_many :files, :autosave => true 
    accepts_nested_attributes_for :files 
    attr_accessible :files_attributes 
end 

然後在控制器,你可以使用@folder.changed_for_autosave?返回是否該記錄已被以任何方式(?new_record?marked_for_destruction?改變)改變,包括它的任何嵌套自動保存關聯是否也同樣發生了變化。

更新。

您可以將模型特定的邏輯從控制器移動到folder模型中的方法e.q. @folder.how_changed?,它可以返回:add_new_file,:delete_file等符號(我同意你這是一個更好的做法,我只是試圖保持簡單)。然後在控制器中,你可以保持邏輯非常簡單。

case @folder.how_changed? 
    when :both 
    redirect_to "both_action" 
    when :add_new_file 
    redirect_to "add_new_file_action" 
    when :delete_file 
    redirect_to "delete_file_action" 
    else 
    redirect_to "folder_not_changed_action" 
end 

該解決方案採用2種方法:每個子模型new_record?marked_for_destruction?,由於Rails 收件箱方法changed_for_autosave?只能是不如何被改變的孩子告訴。這只是如何使用這些指標來實現您的目標。

+0

我不喜歡在控制器中做很多邏輯,這看起來像是一個非常完整的工作方式,我一直在想有辦法使用rails提供的髒指示器。 – Rabbott 2010-10-04 18:48:09

+0

我更新了答案。 – Voldy 2010-10-04 20:27:14