Now that we've finished Chapter 8 of the Rails tutorial, I'll post about Session as an output.
The protocol that underpins the Internet,
stateless. Since there is literally no "state", each
HTTP request does not inherit the information of the previous request.
It is easy to understand by looking at the following example.
"Stateful example" Customer: Hello Clerk: Welcome. Welcome to XX Burger Customer: I'd like a hamburger set Clerk: What would you like to have on the side menu? Customer: With potatoes Clerk: What would you like to drink? Customer: With ginger ale Clerk: How about making a drink L size for +50 yen? Customer: M is fine Clerk: Are you sure you want to do that? Customer: Yes Clerk: I'm clever
"Stateless example" Customer: Hello Clerk: Welcome. Welcome to XX Burger Customer: I'd like a hamburger set Clerk: What would you like to have on the side menu? Customer: Please give me a hamburger set with potatoes Clerk: What would you like to drink? Customer: Please give me a hamburger set with potatoes and ginger ale Clerk: How about making a drink L size for +50 yen? Customer: Please give me a hamburger set with potatoes and ginger ale (M) Clerk: Are you sure you want to do that? Customer: I'd like a hamburger set with potatoes and ginger ale (M). that's all Clerk: I'm clever
stateful example, the clerk (server) remembers the order status of the customer (client) (inheriting the previous information). This is called the application state or session state.
On the other hand, you can see that
stateless does not remember the order status (it does not carry over the previous information). You may be in trouble if you are
stateless. That is when you use features such as
login authentication and
shopping cart. If you forget the previous communication, you need to perform processing such as "login authentication" and "every time you want more products, put everything back in the basket, including the products you put in the past".
session is a function to remember that you are" logged in "so that you do not have to log in again even if you change pages after logging in. In other words, it is a mechanism for realizing stateful communication.
We'll skip creating the controller and routing, and start by creating the login form.
The biggest difference between a session form and a user registration form is that there is no Session model for sessions, so there is no equivalent to an instance variable like @user. Therefore, the information you have to pass to the
form_with helper when creating a new session form is slightly different.
form_with(model: @user, local: true)
Rails automatically determines that "the action of the form is a POST to the URL / users" just by writing as above, but in the case of a session, the scope of the resource (here, the session) and its corresponding You need to specify the URL specifically.
form_with(url: login_path, scope: :session, local: true)
scope:: session => form data goes into: session.
Next, the content entered in the login form is received by the create action of the session controller, and the user is found in the database and verified.
def create user = User.find_by(email: params[:session][:email].downcase) if user && user.authenticate(params[:session][:password]) #Redirect to user information page after user login else #Create an error message render 'new' end end
user = User.find_by(email: params[:session][:email].downcase)
(1) Receive the email address entered in the login form with params, retrieve the user information from the database with find_by, and use the
downcase method to ensure a match when a valid email address is entered.
if user && user.authenticate(params[:session][:password])
(2) Check if user is nil and authenticate with
session[:user_id] = user.id
When you execute the above code, you can save it in the browser with the session method and access the browser like a variable.
#Log in as the passed user def log_in(user) session[:user_id] = user.id end
If you're logged in, use
current_user to return information about that user. Also, use the
if statement to reduce the number of database queries.
#Returns the currently logged in user (if any) def current_user if session[:user_id] @current_user ||= User.find_by(id: session[:user_id]) end end
Then change the layout depending on whether the user is logged in or not. For that, we need a method that returns the logical value of whether we are logged in or not, so we will implement it.
The state in which the user is logged in means that "the user id exists in session", that is, the state where
current_user is not
#Returns true if the user is logged in, false otherwise def logged_in? !current_user.nil? end
Change the layout as follows using the
logged_in? method that returns a logical value.
<% if logged_in? %> #Links for logged-in users <% else %> #Links for users who are not logged in <% end %>
To log out, remove the user ID from the session.
#Log out the current user def log_out session.delete(:user_id) @current_user = nil end