У меня есть трехуровневая многовложенная форма в Rails. Настройка такова: у проектов много вех, а у вех много примечаний. Цель состоит в том, чтобы все можно было редактировать на странице с помощью JavaScript, где мы можем добавлять несколько новых вех в проект на странице и добавлять новые примечания к новым и существующим вехам.
Все работает, как и ожидалось, за исключением того, что когда я добавляю новые заметки к существующей вехе (новые вехи прекрасно работают при добавлении к ним заметок), новые заметки не сохранятся, пока я не отредактирую какое-либо из полей, которые на самом деле относятся к вехе, чтобы пометить форму как «грязную»/отредактированную.
Есть ли способ пометить веху, чтобы новые добавленные заметки сохранялись?
Редактировать: извините, сложно вставить весь код, потому что там так много частей, но вот:
Модели
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 ненавязчивую версию комбинированного помощника/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
Я отображаю форму для ассоциации в скрытом 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;
}
Я предполагаю, что единственным другим соответствующим фрагментом кода, который я могу придумать, будет метод create в 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 создается в следующем перед фильтром:
def load_milestone
@milestone = @project.milestones.find(params[:milestone_id]) if params[:milestone_id]
end
def determine_owner
@owner = load_milestone || @project
end
Дело в том, что все это работает нормально, за исключением случаев, когда я добавляю новые заметки к существующим вехам. Веха должна быть "тронута" для сохранения новых заметок, иначе Rails не обратит внимания.
accept_nested_attributes_for :notes
? также может быть полезен некоторый код. - person Anurag   schedule 12.03.2010