在Rails中将多级嵌套表单标记为"脏"

sim*_*ons 5 ruby forms ruby-on-rails nested-forms

我在Rails中有一个三级多嵌套表单.设置如下:项目有许多里程碑,里程碑有很多笔记.目标是使用JavaScript在页面中编辑所有内容,我们可以在页面中的项目中添加多个新的里程碑,并将新的Notes添加到新的和现有的里程碑.

一切都按预期工作,除了当我向现有的里程碑添加新笔记(新的里程碑在向他们添加笔记时工作正常)时,新笔记将不会保存,除非我编辑任何实际属于里程碑的字段以标记形式"脏"/编辑.

有没有办法标记里程碑,以便添加的新Notes将保存?

编辑:对不起,很难粘贴所有代码,因为有很多部分,但是这里有:

楷模

class Project < ActiveRecord::Base
  has_many :notes, :dependent => :destroy
  has_many :milestones, :dependent => :destroy

  accepts_nested_attributes_for :milestones, :allow_destroy => true
  accepts_nested_attributes_for :notes, :allow_destroy => true, :reject_if => proc { |attributes| attributes['content'].blank? }
end

class Milestone < ActiveRecord::Base
  belongs_to :project
  has_many :notes, :dependent => :destroy

  accepts_nested_attributes_for :notes, :allow_destroy => true, :allow_destroy => true, :reject_if => proc { |attributes| attributes['content'].blank? }
end

class Note < ActiveRecord::Base
  belongs_to :milestone
  belongs_to :project

  scope :newest, lambda { |*args| order('created_at DESC').limit(*args.first || 3) }
end
Run Code Online (Sandbox Code Playgroud)

我正在使用基于jQuery的,不引人注目的Ryan Bates的组合助手/ JS代码来完成这项工作.

应用助手

def add_fields_for_association(f, association, partial)
  new_object = f.object.class.reflect_on_association(association).klass.new
  fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
    render(partial, :f => builder)
  end
end
Run Code Online (Sandbox Code Playgroud)

我在隐藏的div中呈现关联的表单,然后使用以下JavaScript找到它并根据需要添加它.

JavaScript的

function addFields(link, association, content, func) {
    var newID = new Date().getTime();
    var regexp = new RegExp("new_" + association, "g");
    var form = content.replace(regexp, newID);
    var link = $(link).parent().next().before(form).prev();
    if (func) {
        func.call();
    }
    return link;
}
Run Code Online (Sandbox Code Playgroud)

我猜测我能想到的唯一其他相关代码片段是NotesController中的create方法:

def create
  respond_with(@note = @owner.notes.create(params[:note])) do |format|
    format.js   { render :json => @owner.notes.newest(3).all.to_json }
    format.html { redirect_to((@milestone ? [@project, @milestone, @note] : [@project, @note]), :notice => 'Note was successfully created.') }
  end
end
Run Code Online (Sandbox Code Playgroud)

@owner ivar在过滤之前创建如下:

def load_milestone
  @milestone = @project.milestones.find(params[:milestone_id]) if params[:milestone_id]
end

def determine_owner
  @owner = load_milestone || @project
end
Run Code Online (Sandbox Code Playgroud)

事实是,除非我在现有的里程碑中添加新笔记,否则这一切似乎都能正常工作.为了保存新笔记,必须"触及"里程碑,否则Rails不会注意.

Jas*_*red 2

这是Rails 2.3.5 中的bug #4242,已在 Rails 2.3.8 中修复。