Ruby 2.5.7 Rails 5.2.4
gem gem 'devise'
The new registration form of devise can be customized (not the default state)
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.
new.html.erb
) and a completion screen (completion.html.erb
) in views / users) after membership registration to controllers (
controllers / users / registrations_controller.rb`).registrations_controller.rb
to routes.rb
.controllers / users_controller.rb
)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.
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 is
registrations / 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.
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 with
form_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.
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.
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`.
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
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.
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