2010-09-17 114 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

相关问题