rails-multistep-form
rails-multistep-form copied to clipboard
Dealing with Nested Forms
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?
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:
Nope, I've never tested it with nested models so it might need some tweaking. That should probably be on my to-do list.
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
did you get this working?
I'm also interested on this!
@jteneycke +1 thanks for the fix
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.
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 Nice catch, thanks! I'll have to give this some thought. Definitely a legit bug though.
@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!