[RUBY] [Rails] Add a confirmation screen and a completion screen to devise membership registration.

environment

Ruby 2.5.7 Rails 5.2.4

gem gem 'devise'

Premise

The new registration form of devise can be customized (not the default state)

Thing you want to do

In the default setting of devise, when information is entered and sent on the sign_up page, it will be registered as it is and will transition to the pre-specified (designated) page. I think it would be more kind if there was a page where you can check the information entered before registration, or a page to notify you that registration was completed, so this time, in addition to the "input form", "entered" We will create an "information confirmation screen" and a "registration completion screen". As for the flow of pages completed by this creation, New member information input form ʻusers / new.html.erb (new creation) → Input information confirmation screen ʻusers / registrations / new.html.erb → Registration completion screen ʻusers / completion (new creation)` The screen will change in order.

It may seem a little strange, but ʻusers / registrations / new.html.erb` provided by devise only confirms the information entered on the previous page, and it looks like it is entered on the previous page. It just displays the value that was given.

procedure

  1. Prepare an input screen (new.html.erb) and a completion screen (completion.html.erb) in views / users
  2. Add the redirect destination (ʻusers / completion.html.erb) after membership registration to controllers (controllers / users / registrations_controller.rb`).
  3. Added the routing of the view file added in 1. and the use of registrations_controller.rb to routes.rb.
  4. Create new and completion for render in (controllers / users_controller.rb)

1. Creation of confirmation screen and completion screen

As mentioned at the beginning, the flow of the screen at the time of new registration is New registration input form ʻusers / new.html.erb → Input confirmation screen ʻusers / registrations / new.html.erb → Registration completion screen ʻusers / completion`. If you press the "Register" button on the confirmation screen, user information will be registered using the standard function of devise.

input screen

erb:users/new.html.erb


<div>

  <h2>New member registration</h2>

  <%= form_with url: new_user_registration_path, method: :get, local: true do |f| %>

    <%= f.label :name %>
    <%= f.text_field :name %>

    <%= f.label :phone_number %>
    <%= f.number_field :phone_number %>

    <%= f.label :email %>
    <%= f.email_field :email %>

    <%= f.label :password %>
    <% if @minimum_password_length %>
      (<%= @minimum_password_length %>More than letters)
    <% end %>

    <%= f.password_field :password %>
    <%= f.password_field :password_confirmation %>

    <%= render "users/shared/links" %>

    <%= f.submit "Verification" %>
  <% end %>
</div>

Create a new one by referring to the originally prepared registrations / new.html.erb form. I will omit the method of adding name and phone number information to the registration information. If you want to add it, please set it first and check the operation, then try this method, or try with the default settings (email address, password only) without increasing the number of columns.

The point is the form tag.

erb:users/new.html.erb



  ...

  <%= form_with url: new_user_registration_path, method: :get, local: true do |f| %>

    ...

  <% end %>

Here, the model to be saved is not specified, only the url is specified. In other words, when submitted in the form, it will transition to the url specified here, and the value entered in the form will also be passed to the transition destination as a "parameter". For the url specified here, specify ʻurl: new_user_registration_pathon the next confirmation screen. This url isregistrations / new.html.erb` provided by devise by default.

The HTTP method specifies "GET" instead of "POST" because this form only transitions the url. The form's HTTP method defaults to "POST", so you need to specify method:: get.

The form tag used this time is form_with. Since the default transmission method of form_with is Ajax (remote: true) and the screen transition is not performed, it is necessary to specify local: true as well. In the case of form_for, the default is local: true, so you don't usually need to be aware of it.

confirmation screen

erb:users/registration/new.html.erb


<div>

  <h2>Confirmation of input information</h2>

  <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>

    <p><%= params[:name] %></p>
    <p><%= params[:phone_number] %></p>
    <p><%= params[:email] %></p>
    <p><%= @password %></p>

    <%#Parameters to actually send%>
    <%= f.hidden_field :name, value: params[:name] %>
    <%= f.hidden_field :phone_number, value: params[:phone_number] %>
    <%= f.hidden_field :email, value: params[:email] %>
    <%= f.hidden_field :password, value: params[:password] %>

    <%= f.submit "sign up" %>

  <% end %>
</div>

This screen is ʻusers / registrations / new.html.erbprepared by devise. Originally this page has an input form, but this time it's just a confirmation, so I won't show the form. The original form tags starting withform_for` are used as they are.

Get the parameters passed from the previous page using params [: name] etc. and display them for confirmation.

Since <p> <% = @password%> </ p> blinds the password, the params [: password] passed from the previous page is processed first on the controller side. The method of blinding is as follows. (Although it is listed in the parameters, I did not know how to hide it here, so I would appreciate it if you could teach me a detailed person.)

users/registrations_controller.rb


class Users::RegistrationsController < Devise::RegistrationsController

  ...

  #Uncomment the new action and add the following above super
  def new
    i = 0
    @password = ""
    while i < params[:password].length
      @password += "*"
      i += 1
    end
    super
  end

  ...

end

I am getting the number of characters in the password with params [: password] .length. With while i <params [: password] .length ... end, ʻicounts up by 1 in the process. At the same time," * "is added to the variable@ password =" "which was defined immediately before, and the process ends when the number of characters is reached. Then display the contents of the<% = @password%>` variable in the view.

super means that the setting in Devise :: RegistrationsController is inherited as it is, and without this description, resource and resource_name in form_for cannot be used, so be careful not to delete them. ..

erb:users/registration/new.html.erb


<%= f.hidden_field :name_family, value: params[:name] %>
...

f.hidden_field is not displayed, but thevalue: params [: name]specified there is submitted as a form. Since the model to be saved in this form is also specified (devise is automatically specified in resource), the value specified in this f.hidden_field will be the value to be saved as it is.

Completion screen

erb:users/completion.html.erb


<div>
  <% if request.referrer.include?('users/sign_up') %>
    <p>Registration has been completed!</p>
  <% else %>
    <p>already used.</p>
  <% end %>
</div>

If you press Register on the previous page, the confirmed member information will be saved and you will be taken to this screen at the same time.

You can use request.referrer to get the URL of the previous page from which page you moved to here. The include? method of request.referrer.include? ('users / sign_up') is a method that returns whether the value in () is included in it. Here we determine if ʻusers / sign_up was included in the URL of the previous page and change the text displayed on that page. ʻIf the transition is from other than users / registrations / new.html.erb, it will be displayed as registered, and if you try to display it if it is not registered (not logged in) in the first place, devise's before_action: authenticate_user! The page will be redirected to.

2. Add new and completion to users_controller.rb

In the previous step, the view file was created, but since the screen cannot be displayed as it is, it is necessary to describe the action in the controller.

users_controller.rb


class UsersController < ApplicationController

  before_action :authenticate_user!, except: %i[new]

  ...

  def new
  end

  def completion
  end

  ...

end

Since the new page is a new member registration form, it is necessary to describe as follows. before_action :authenticate_user!, except: %i[new] before_action :authenticate_user!, except: [:new] before_action :authenticate_user!, except: :new They all have the same meaning, but when you write more actions, the code gets shorter on the first line.

By the way, when you specify more than one with % i, just separate them with a space likebefore_action: authenticate_user !, except:% i [new action1 action2 action3].

If you haven't logged in, you want to redirect completion, so don't include it in ʻexcept`.

3. Write the newly created view and users / registrations_controller.rb in routes.rb

routes.rb


Rails.application.routes.draw do

  ...

  # registrations_controller.Enable rb.
  devise_for :users, controllers: {
    ...
    registrations: 'users/registrations'
  }

  #Created users/new.html.erb and users/completion.html.Add erb to the routing.
  resources :users, only: %i[new] do
    get 'completion', to: 'users#completion'
  end

end

4. Change the redirect destination after registration

When Register is pressed on the confirmation screen, it is necessary to transition to ʻusers / completion.html.erb` prepared in the previous step.

users/registrations_controller.rb


class Users::RegistrationsController < Devise::RegistrationsController

  ...

  def after_sign_up_path_for(resource)
    user_completion_path(resource)
  end

  ...

end

I think that the redirect destination is the default or optionally another page, but set that path to ʻuser_completion_path (resource)` (path of users / completion.html.erb) created in the previous step. I will.

Summary

For more practical usage, I have published the file I am actually using on my GitHub, so please refer to that as well! GitHub - MasaoSasaki/matchi

If you have any questions, differences in interpretation, or any discomfort in the description method, we would appreciate it if you could point them out in the comments.

Thank you for reading until the end.

Recommended Posts

[Rails] Add a confirmation screen and a completion screen to devise membership registration.
[Rails] Add column to devise
[Rails] Add strong parameters to devise
[Rails] [Memo] When to add = to <%%> and when not
[Rails] Introduce a simple calendar and insert a "confirmation screen" in additional events
[Rails] How to create a table, add a column, and change the column type
Find out about Rails hidden_field (create a confirmation screen and check the behavior)
Implement a reservation system using Rails and simple calendar! Let's add validation to datetime!
Display a confirmation screen before registering a record with rails
[Rails] How to edit and customize devise view and controller
[Rails] Processing after adding a column to the devise table
Add a shadow to the Swift Button (and also the circle)
Implement user registration function and corporate registration function separately in Rails devise
[Rails] How to install devise
[Rails 6] How to create a dynamic form input screen using cocoon
I want to add devise in Rails, but I can't bundle install
[Caution !!] Precautions when converting Rails devise and view files to haml
[Reading impression] "How to learn Rails, how to write a book, and how to teach"
[Rails 5] How to display the password change screen when using devise
[Rails] How to use gem "devise"
How to add columns to a table
Add a search function in Rails.
Preparing to create a Rails application
[rails] Login screen implementation in devise
[Rails] How to prevent screen transition
[Rails] How to add new pages
How to make a splash screen
[Rails] "Input"-> "Confirmation screen"-> "Save"-> "View"
[Rails] How to log in with a name by adding a devise name column
I was a little addicted to running old Ruby environment and old Rails
How to update user edits in Rails Devise without entering a password
[Rails 6] cocoon_ Add id and data attributes to the form to be added
[Rails] devise customization. How to change the redirect page after user registration and editing, and how to skip password input when editing