我有以下表单对象来管理复杂的嵌套表单。
表格
= 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
时,会调用该操作。
那么我应该如何重构这个表格呢? update
下面的代码会创建另一个Profile对象。
答案 0 :(得分:6)
simple_form_for
在内部使用form_for
来完成其工作。 form_for
使用方法persisted?
来确定对象是否已经持久存储在数据库中。如果它已被持久化form_for
将生成一个带有方法 PUT 的表单来更新对象,否则它将生成一个带有方法 POST 的表单来创建新对象。因此,您必须为表单对象实现persisted?
方法。你可以像这样实现它:
class ProfileForm
# ...
def persisted?
@person.persisted? && @profile.persisted?
end
# ...
end
更新如果@person
为nil
,即Person
没有关联Profile
,我想您会创建一个新的Person
@profile
与ProfileForm
相关联。在这种情况下,只要至少persisted?
为@profile
,就可以安全地假设persisted?
为class ProfileForm
# ...
def persisted?
@profile.persisted?
end
# ...
end
,因此:
undefined local variable or method `id'
更新要避免错误id
,您必须为ProfileForm
定义class ProfileForm
# ...
def id
@profile.id
end
# ...
end
方法,如下所示:
{{1}}
答案 1 :(得分:0)
replace
= simple_form_for(@profile_form, :url => profiles_path) do |f|
with
= simple_form_for(@profile_form, :url => {:controller => "profiles"}) do |f|
答案 2 :(得分:0)
请看这里:http://apidock.com/rails/ActionView/Helpers/FormHelper/apply_form_for_options!
您应该编写方法ProfileForm#persisted?
,以便在您希望表单更新记录时返回true
。