rails-multistep-form icon indicating copy to clipboard operation
rails-multistep-form copied to clipboard

Dealing with Nested Forms

Open jteneycke opened this issue 11 years ago • 10 comments

I'm using this multi-step form pattern with a model accepts_nested_attributes_for two other models.

#  id                 :integer          not null, primary key
#  pickup_address_id  :integer
#  dropoff_address_id :integer
#  items              :text
#  created_at         :datetime
#  updated_at         :datetime

class Order < ActiveRecord::Base
  belongs_to :pickup_address, class_name: "Address"
  accepts_nested_attributes_for :pickup_address

  belongs_to :dropoff_address, class_name: "Address"
  accepts_nested_attributes_for :dropoff_address

  include MultiStepModel

  def self.total_steps
    3
  end
end

When I was building this out, I found that it wouldn't render the f.fields_for unless I put build_ in the create and new actions. Now it renders the nested fields, but the values I'm entering aren't saving to the database.

class OrdersController < ApplicationController

  ...

  def new
    wizard = ModelWizard.new(Order, session).start
    @order = wizard.object
    @order.build_pickup_address
    @order.build_dropoff_address
  end

  def edit
    ModelWizard.new(@order, session).start
  end

  def create
    wizard = ModelWizard.new(Order, session, params).process
    @order = wizard.object
    @order.build_pickup_address
    @order.build_dropoff_address
    if wizard.save
      redirect_to @order, notice: "Order saved!"
    else
      render :new
    end
  end

  def update
    wizard = ModelWizard.new(@order, session, params).process
    if wizard.save
      redirect_to @order, notice: 'Order was successfully updated.'
    else
      render action: 'edit'
    end
  end

  ...

end

Any thoughts?

jteneycke avatar Oct 10 '13 04:10 jteneycke

Ah! Just realized I'm a duplicate of #1!

@nerdcave I know you mentioned in #2 that this project doesn't have strong parameters because it's not needed to demonstrate a form wizard, but are there any specific considerations you can think of using this gem/pattern with nested nested models? :smile:

jteneycke avatar Oct 10 '13 05:10 jteneycke

Nope, I've never tested it with nested models so it might need some tweaking. That should probably be on my to-do list.

nerdcave avatar Oct 12 '13 14:10 nerdcave

I was really stoked for this pattern and then I had all these issues so I did it from scratch Railscast style, and one of the things I learned doing that was that the @order.build_whatever has to be run conditionally depending on which step the form is on so that build doesn't blank out the nested model.

Update: I used the same trick with this project and it worked. I have 3 steps, the first and the third are nested f.fields_for. Checking @order.step(3) didn't build the form so I tried 2 and it worked.

 def new
    wizard = ModelWizard.new(Order, session).start
    @order = wizard.object
    @order.build_pickup_address
    @order.build_dropoff_address
  end

  def edit
    ModelWizard.new(@order, session).start
  end

  def create
    wizard = ModelWizard.new(Order, session, params).process
    @order = wizard.object

    if @order.step?(1)
      @order.build_pickup_address
    end
    if @order.step?(2)
      @order.build_dropoff_address
    end

    if wizard.save
      redirect_to @order, notice: "Order saved!"
    else
      render :new
    end
  end

jteneycke avatar Oct 12 '13 14:10 jteneycke

did you get this working?

lucienjarrett avatar Jul 25 '14 22:07 lucienjarrett

I'm also interested on this!

shamanime avatar Aug 12 '14 23:08 shamanime

@jteneycke +1 thanks for the fix

kitwalker12 avatar Aug 13 '14 07:08 kitwalker12

Ok, I worked a nested model into the example: https://github.com/nerdcave/rails-multistep-form/commit/891ffe124185d7eb533ab14724eefd5c01c0613f. Basically, a Product has_many :categories and accepts_nested_attributes_for :categories (would work just as well with a has_one). Category's name validates only on the step it's shown.

It actually worked right off, I didn't have to tweak anything. However, if your nested model has multiple fields that you're trying to split up on multiple steps, that probably won't work.

nerdcave avatar Aug 14 '14 01:08 nerdcave

I had the same problem that I have on my project with nested fields.

Go to step 2, press the "go back" button without filling the category name, click next and get the "Categories name can't be blank" error while on step 1.

shamanime avatar Aug 14 '14 20:08 shamanime

@shamanime Nice catch, thanks! I'll have to give this some thought. Definitely a legit bug though.

nerdcave avatar Aug 18 '14 14:08 nerdcave

@shamanime Do you get this to work? I'm having the exact same issue with nested address fields on step 3. Go back, then forward and I get, "Address 1 can't be blank", etc.

Thanks!

Terris avatar Nov 18 '15 19:11 Terris