How should I handle the edit and update action when using a form object?

I have the following form object to manage a complex nested form.

The 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 edit an object using this create form, an action is called. How should I reorganize this form? The code below on update creates another Profile object.

+7
source share
3 answers

simple_form_for uses form_for internally to do its job. form_for uses persisted? method persisted? to decide whether an object is stored in the database or not. If it is already saved, form_for will generate a form with the PUT method to update the object, otherwise it will generate a form with the POST method to create a new object. So you need to implement persisted? method persisted? to create an object. You can implement it as follows:

 class ProfileForm # ... def persisted? @person.persisted? && @profile.persisted? end # ... end 

Update In the case of @person there is nil , that is, there is no Person associated with Profile , I suppose you would create a new Person to communicate with @profile . In this case, is it safe to assume that a ProfileForm is persisted? if at least @profile is persisted? , thus:

 class ProfileForm # ... def persisted? @profile.persisted? end # ... end 

Refresh To avoid the undefined local variable or method `id' error, you must define the id method for ProfileForm , for example:

 class ProfileForm # ... def id @profile.id end # ... end 
+6
source
 replace = simple_form_for(@profile_form, :url => profiles_path) do |f| with = simple_form_for(@profile_form, :url => {:controller => "profiles"}) do |f| 
0
source

Take a look here: http://apidock.com/rails/ActionView/Helpers/FormHelper/apply_form_for_options!

Do you have to write the ProfileForm#persisted? method ProfileForm#persisted? so that it returns true if you want the form to update your record.

0
source

All Articles