当我使用表单对象时,我应该如何处理编辑和更新操作?

时间:2013-06-12 11:19:58

标签: ruby-on-rails ruby ruby-on-rails-3 forms object

我有以下表单对象来管理复杂的嵌套表单。

表格

= 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对象。

3 个答案:

答案 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

更新如果@personnil,即Person没有关联Profile,我想您会创建一个新的Person @profileProfileForm相关联。在这种情况下,只要至少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