DEV Community

Ian Kamau
Ian Kamau

Posted on

Building a multi-step form in Ruby on Rails

Many web applications require you to build a multi step form especially for things like user registration or checkout flow.
In this blog, we will walk through how to create a multi-step form in Ruby on Rails.

🧩 Why Use a Multi-Step Form?

Let’s quickly look at why you might want a multi-step form:

  1. Increases completion rates as users are more likely to finish shorter steps than one long form.

  2. Improves UX: Long forms can overwhelm users. Breaking them into steps makes the process feel lighter.

🛠️ What We’re Building

We’ll build a multi-step form for creating a user profile with the following steps:

  1. Personal Info (name, email)
  2. Address Info (street, city, state)

We’ll implement this using only core Rails features — leveraging Turbo Frames and Turbo Streams from the Hotwire stack — to create dynamic, multi-step forms without full page reloads or third-party gems.

📦 Prerequisites

  • Basic knowledge of Rails controllers, views, models, and forms
  • Basic knowledge of turbo_frame_tag and turbo_stream

🚀 Step-by-Step Implementation

Create a new app

rails new multistep_form_app
cd multistep_form_app
rails db:create
Enter fullscreen mode Exit fullscreen mode

Scaffold User

This will create the controller, views, model, migration and also update the routes file

rails generate scaffold User name:string email:string street:string city:string state:string
rails db:migrate
Enter fullscreen mode Exit fullscreen mode

Update root route to root "users#index"

Image description

And your page should look like this

Image description

Multi step logic

Now we want the new.html.erb view file on app/views/users/ to be a multi form.

Step 1 - Split the form partial

In the form partial, update the route and wrap both the name and email fields in a turbo_frame_tag "step1"

It should be like this

Image description

Step 2 - Create step2 partial

In app/views/users create a new partial file and name it _step2.html.erb. This is where we will have Address information and submit button.

Add the following code to it

Image description

Step 3 - Create collection route on user resource

Add a collection to the users resource route.
This route will be used when submitting each step of the form.

resources :users do
    collection do
      post "next_step"
    end
  end
Enter fullscreen mode Exit fullscreen mode

Image description

Step 4 - Create next_step method on users_controller.rb

Add this method to users_controller.rb

def next_step
    @name, @email, @next_step = params.values_at(:name, :email, :step)
    respond_to do |format|
      format.html
      format.turbo_stream
    end
  end
Enter fullscreen mode Exit fullscreen mode

On the next_step method, we will grab and save both name and email and also the current step.
We will be using turbo_stream to replace step1 contents with step2 contents

Final step

On app/views/users create a file next_step.turbo_stream.erb and add the following code to it

<%= turbo_stream.replace "step#{@next_step.to_i}" do %>
  <%= render partial: "step#{@next_step.to_i + 1}", locals: { name: @name, email: @email } %>
<% end %>
Enter fullscreen mode Exit fullscreen mode

The code above basically replaces anything with turbo frame tag "step#{@next_step.to_i}" which in our case is step1with the partial file we created earlier step2.

It also passes the 2 variable (name & email) to the partial.

Now with that, you can create a new user.

Your final form should look like this

Image description

Image description

Image description

Image description

Image description

✅ Optional Enhancements

  • Add validation logic before proceeding to the next step
  • Allow users to go back to previous steps
  • Style the form with Tailwind or Bootstrap
  • Add a progress indicator

Access Source Code here https://github.com/Iank-code/multi_step_form_rails

Top comments (0)