Ruby on Rails: Building a RESTful API with Ruby on Rails and JWT Au......
rails new multi_step_form cd multi_step_form
rails generate model User email:string password_digest:string rails generate model Profile first_name:string last_name:string user:references rails generate model Address street:string city:string zip:string user:references
rails db:migrate
# Gemfile gem 'bcrypt', '~> 3.1.7'
bundle install
# app/models/user.rb class User < ApplicationRecord has_secure_password has_one :profile has_one :address end
mkdir app/forms
# app/forms/user_form.rb class UserForm include ActiveModel::Model attr_accessor :email, :password, :password_confirmation validates :email, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP } validates :password, presence: true, confirmation: true end
# app/forms/profile_form.rb class ProfileForm include ActiveModel::Model attr_accessor :first_name, :last_name validates :first_name, :last_name, presence: true end
# app/forms/address_form.rb class AddressForm include ActiveModel::Model attr_accessor :street, :city, :zip validates :street, :city, :zip, presence: true end
rails generate controller Registration new_user new_profile new_address create
# app/controllers/registration_controller.rb class RegistrationController < ApplicationController def new_user @user_form = UserForm.new(session[:user_form]) end def new_profile redirect_to new_user_registration_path unless session[:user_form] @profile_form = ProfileForm.new(session[:profile_form]) end def new_address redirect_to new_user_registration_path unless session[:user_form] && session[:profile_form] @address_form = AddressForm.new(session[:address_form]) end def create @user_form = UserForm.new(session[:user_form]) @profile_form = ProfileForm.new(session[:profile_form]) @address_form = AddressForm.new(session[:address_form]) if @user_form.valid? && @profile_form.valid? && @address_form.valid? user = User.create!( email: @user_form.email, password: @user_form.password ) user.create_profile!( first_name: @profile_form.first_name, last_name: @profile_form.last_name ) user.create_address!( street: @address_form.street, city: @address_form.city, zip: @address_form.zip ) reset_session redirect_to root_path, notice: 'Registration completed successfully!' else render :new_user end end def update_user @user_form = UserForm.new(user_form_params) if @user_form.valid? session[:user_form] = user_form_params redirect_to new_profile_registration_path else render :new_user end end def update_profile @profile_form = ProfileForm.new(profile_form_params) if @profile_form.valid? session[:profile_form] = profile_form_params redirect_to new_address_registration_path else render :new_profile end end def update_address @address_form = AddressForm.new(address_form_params) if @address_form.valid? session[:address_form] = address_form_params redirect_to create_registration_path else render :new_address end end private def user_form_params params.require(:user_form).permit(:email, :password, :password_confirmation) end def profile_form_params params.require(:profile_form).permit(:first_name, :last_name) end def address_form_params params.require(:address_form).permit(:street, :city, :zip) end end
<!-- app/views/registration/new_user.html.erb --> <h2>Step 1: User Information</h2> <%= form_with model: @user_form, url: update_user_registration_path, method: :patch do |form| %> <div> <%= form.label :email %> <%= form.email_field :email %> </div> <div> <%= form.label :password %> <%= form.password_field :password %> </div> <div> <%= form.label :password_confirmation %> <%= form.password_field :password_confirmation %> </div> <%= form.submit "Next" %> <% end %>
<!-- app/views/registration/new_profile.html.erb --> <h2>Step 2: Profile Information</h2> <%= form_with model: @profile_form, url: update_profile_registration_path, method: :patch do |form| %> <div> <%= form.label :first_name %> <%= form.text_field :first_name %> </div> <div> <%= form.label :last_name %> <%= form.text_field :last_name %> </div> <%= form.submit "Next" %> <% end %>
<!-- app/views/registration/new_address.html.erb --> <h2>Step 3: Address Information</h2> <%= form_with model: @address_form, url: update_address_registration_path, method: :patch do |form| %> <div> <%= form.label :street %> <%= form.text_field :street %> </div> <div> <%= form.label :city %> <%= form.text_field :city %> </div> <div> <%= form.label :zip %> <%= form.text_field :zip %> </div> <%= form.submit "Finish" %> <% end %>
# config/routes.rb Rails.application.routes.draw do root "welcome#index" resource :registration, only: [] do get :new_user, on: :collection patch :update_user, on: :collection get :new_profile, on: :collection patch :update_profile, on: :collection get :new_address, on: :collection patch :update_address, on: :collection get :create, on: :collection end end
# test/forms/user_form_test.rb require "test_helper" class UserFormTest < ActiveSupport::TestCase test "valid user form" do form = UserForm.new(email: "[email protected]", password: "password", password_confirmation: "password") assert form.valid? end test "invalid without email" do form = UserForm.new(password: "password", password_confirmation: "password") assert_not form.valid? end end
# test/integration/registration_flow_test.rb require "test_helper" class RegistrationFlowTest < ActionDispatch::IntegrationTest test "successful registration" do get new_user_registration_path assert_response :success patch update_user_registration_path, params: { user_form
Sign up for free and be the first to get notified about new posts.
1 comment
This was so helpful thanks a lot and cheers this tutorial was so detailed and educational thanks again.