I have following form object to managing complicated nested form.
我有跟随表单对象来管理复杂的嵌套表单。
Form
= simple_form_for(@profile_form, :url => profiles_path) do |f|
...
Routes
resources :profiles
Controller
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
Form Object
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
But right now when I'm editing object using this form create
action is called. How should then I refactor this form? Code below on update
creates another Profile object.
但是现在当我使用这个表单编辑对象时,会调用create action。那么我应该如何重构这个表格呢?更新下面的代码创建另一个Profile对象。
3 个解决方案
#1
6
simple_form_for
uses form_for
internally to do its job. form_for
uses the method persisted?
to decide if the object is already persisted on the database or not. If it is already persisted form_for
will generate a form with method PUT to update the object, otherwise it will generate a form with method POST to create the new object. Therefore you have to implement the persisted?
method for you form object. You could implement it like this:
simple_form_for在内部使用form_for来完成它的工作。 form_for使用持久化的方法?判断对象是否已持久存储在数据库中。如果已经持久化,form_for将生成一个带有方法PUT的表单来更新对象,否则它将生成一个带有方法POST的表单来创建新对象。因此你必须实现持久化?你形成对象的方法。您可以像这样实现它:
class ProfileForm
# ...
def persisted?
@person.persisted? && @profile.persisted?
end
# ...
end
Update In the case @person
is nil
, i.e. there's no Person
associated to the Profile
, I suppose you would create a new Person
to associate to the @profile
. In this case it is safe to assume that a ProfileForm
is persisted?
as long as at least the @profile
is persisted?
, thus:
更新如果@person是nil,即没有与Profile关联的Person,我想你会创建一个新的Person来关联@profile。在这种情况下,可以安全地假设ProfileForm是持久的吗?只要至少@profile是持久的?,因此:
class ProfileForm
# ...
def persisted?
@profile.persisted?
end
# ...
end
Update To avoid the error undefined local variable or method `id'
you have to define the id
method for ProfileForm
, like this:
更新为避免错误未定义的局部变量或方法`id',您必须为ProfileForm定义id方法,如下所示:
class ProfileForm
# ...
def id
@profile.id
end
# ...
end
#2
0
replace
= simple_form_for(@profile_form, :url => profiles_path) do |f|
with
= simple_form_for(@profile_form, :url => {:controller => "profiles"}) do |f|
#3
0
Look here: http://apidock.com/rails/ActionView/Helpers/FormHelper/apply_form_for_options!
请看这里:http://apidock.com/rails/ActionView/Helpers/FormHelper/apply_form_for_options!
You should write method ProfileForm#persisted?
so that it returns true
if you want form to update your record.
你应该写方法ProfileForm #dupisted?如果您希望表单更新您的记录,则返回true。
#1
6
simple_form_for
uses form_for
internally to do its job. form_for
uses the method persisted?
to decide if the object is already persisted on the database or not. If it is already persisted form_for
will generate a form with method PUT to update the object, otherwise it will generate a form with method POST to create the new object. Therefore you have to implement the persisted?
method for you form object. You could implement it like this:
simple_form_for在内部使用form_for来完成它的工作。 form_for使用持久化的方法?判断对象是否已持久存储在数据库中。如果已经持久化,form_for将生成一个带有方法PUT的表单来更新对象,否则它将生成一个带有方法POST的表单来创建新对象。因此你必须实现持久化?你形成对象的方法。您可以像这样实现它:
class ProfileForm
# ...
def persisted?
@person.persisted? && @profile.persisted?
end
# ...
end
Update In the case @person
is nil
, i.e. there's no Person
associated to the Profile
, I suppose you would create a new Person
to associate to the @profile
. In this case it is safe to assume that a ProfileForm
is persisted?
as long as at least the @profile
is persisted?
, thus:
更新如果@person是nil,即没有与Profile关联的Person,我想你会创建一个新的Person来关联@profile。在这种情况下,可以安全地假设ProfileForm是持久的吗?只要至少@profile是持久的?,因此:
class ProfileForm
# ...
def persisted?
@profile.persisted?
end
# ...
end
Update To avoid the error undefined local variable or method `id'
you have to define the id
method for ProfileForm
, like this:
更新为避免错误未定义的局部变量或方法`id',您必须为ProfileForm定义id方法,如下所示:
class ProfileForm
# ...
def id
@profile.id
end
# ...
end
#2
0
replace
= simple_form_for(@profile_form, :url => profiles_path) do |f|
with
= simple_form_for(@profile_form, :url => {:controller => "profiles"}) do |f|
#3
0
Look here: http://apidock.com/rails/ActionView/Helpers/FormHelper/apply_form_for_options!
请看这里:http://apidock.com/rails/ActionView/Helpers/FormHelper/apply_form_for_options!
You should write method ProfileForm#persisted?
so that it returns true
if you want form to update your record.
你应该写方法ProfileForm #dupisted?如果您希望表单更新您的记录,则返回true。