将多级嵌套表单标记为“脏".在Rails中 [英] Marking multi-level nested forms as "dirty" in Rails
问题描述
我在Rails中有一个三层的多嵌套表单.设置是这样的:项目有很多里程碑,而里程碑有很多注释.我们的目标是使用JavaScript在页面中进行所有内容的编辑,我们可以在页面中的项目中添加多个新的里程碑,并在新的和现有的里程碑中添加新的Notes.
I have a three-level multi-nested form in Rails. The setup is like this: Projects have many Milestones, and Milestones have many Notes. The goal is to have everything editable within the page with JavaScript, where we can add multiple new Milestones to a Project within the page, and add new Notes to new and existing Milestones.
一切正常,除了将新注释添加到现有里程碑(将新注释添加到它们时,新里程碑工作正常)之外,除非我编辑了以下任何一项,否则不会保存新注释实际属于里程碑的字段,以标记为脏"/已编辑形式.
Everything works as expected, except that when I add new notes to an existing Milestone (new Milestones work fine when adding notes to them), the new notes won't save unless I edit any of the fields that actually belong to the Milestone to mark the form "dirty"/edited.
是否可以标记里程碑,以便保存已添加的新便笺?
Is there a way to flag the Milestone so that the new Notes that have been added will save?
对不起,由于有很多部分,因此很难粘贴所有代码,但是这里有:
sorry, it's hard to paste in all of the code because there's so many parts, but here goes:
模型
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
我正在使用基于jQuery的Ryan Bates组合助手/JS代码的简单版本来完成此操作.
I'm using an jQuery-based, unobtrusive version of Ryan Bates' combo helper/JS code to get this done.
应用程序帮助程序
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
我在一个隐藏的div中呈现该关联的表单,然后使用以下JavaScript查找并根据需要添加它.
I render the form for the association in a hidden div, and then use the following JavaScript to find it and add it as needed.
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;
}
我猜我唯一能想到的其他相关代码段就是NotesController中的create方法:
I'm guessing the only other relevant piece of code that I can think of would be the create method in the NotesController:
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
@owner ivar是在以下过滤器之前创建的:
The @owner ivar is created in the following before filter:
def load_milestone
@milestone = @project.milestones.find(params[:milestone_id]) if params[:milestone_id]
end
def determine_owner
@owner = load_milestone || @project
end
事实是,所有这些似乎都可以正常运行,除非我要在现有里程碑中添加新注释.为了保存新笔记,必须触摸"里程碑,否则Rails不会关注.
Thing is, all this seems to work fine, except when I'm adding new notes to existing milestones. The milestone has to be "touched" in order for new notes to save, or else Rails won't pay attention.
推荐答案
这是已修复在Rails 2.3.8中.
This is bug #4242 in Rails 2.3.5 and it has been fixed in Rails 2.3.8.
这篇关于将多级嵌套表单标记为“脏".在Rails中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!