我有跟随表单对象来管理复杂的嵌套表单.
形成
= simple_form_for(@profile_form,:url => profiles_path) do |f| ...
路线
resources :profiles
调节器
class ProfilesController < ApplicationController def new @profile_form = ProfileForm.new end def edit @profile_form = ProfileForm.new(params[:id]) end def create @profile_form = ProfileForm.new if @profile_form.submit(params[:profile_form]) redirect_to @profile_form.profile,notice: 'Profile was successfully created.' else render action: "new" end end def update @profile_form = ProfileForm.new(params[:id]) if @profile_form.submit(params[:profile_form]) redirect_to @profile_form.profile,notice: 'Profile was successfully updated.' else render action: "edit" end end end
表格对象
class ProfileForm include ActiveModel::Validations include ActiveModel::Conversion extend ActiveModel::Naming def initialize(profile_id = nil) if profile_id @profile = Profile.find(profile_id) @person = profile.person end end ... def submit(params) profile.attributes = params.slice(:available_at) person.attributes = params.slice(:first_name,:last_name) if valid? profile.save! person.save! true else false end end def self.model_name ActiveModel::Name.new(self,nil,"Profile") end def persisted? false end end
但是现在当我使用这个表单编辑对象时,会调用create action.
那么我应该如何重构这个表格呢?更新下面的代码创建另一个Profile对象.
解决方法
simple_form_for在内部使用form_for来完成它的工作. form_for使用持久化的方法?判断对象是否已持久存储在数据库中.如果已经持久化,form_for将生成一个带有方法PUT的表单来更新对象,否则它将生成一个带有方法POST的表单来创建新对象.因此你必须实现持久化?你形成对象的方法.您可以像这样实现它:
class ProfileForm # ... def persisted? @person.persisted? && @profile.persisted? end # ... end
更新如果@person是nil,即没有与Profile关联的Person,我想你会创建一个新的Person来关联@profile.在这种情况下,可以安全地假设ProfileForm是持久的吗?只要至少@profile是持久的?,因此:
class ProfileForm # ... def persisted? @profile.persisted? end # ... end
更新为避免错误未定义的局部变量或方法`id’,您必须为ProfileForm定义id方法,如下所示:
class ProfileForm # ... def id @profile.id end # ... end