こんにちは!まろんぼーいです。
今回は、「初心者がWebアプリを作ってみた」シリーズの第12回です。
このシリーズでは、過去に完全初心者の僕が作ったWebアプリを参考に、
初心者なりに試行錯誤しながらその改良版を一から作っていく過程をお見せしています。
このシリーズのモットーは、「同様の初心者が、アプリ作成の流れをつかみながら同様のアプリを作れるようになること」です。
ということで、基本的にアプリを作成していく過程を順を追って解説していますが、
「正確な内容」よりも、「わかりやすいなんとなくのイメージ」を重視して記事を書いています。
経験者の方からすると、「正確にはちがう!」と突っ込みたくなるような内容もあるかと思いますが、
難しい知識よりも、なんとなくでいいので流れをつかむ!
そんな内容となっていますので、同じ初心者の方の参考になればうれしいです!
それでは今回もはじめていきましょう!
〇前回までの進捗
前回は、Userの新規登録画面を作成しました。
viewファイルでいうと、new.html.erbです。
これまでのindex、showとは異なり、form_with文を用いてユーザが入力するフォームを作成しましたね。
フォームは本記事のログイン画面含めいろいろなページで使うので、form_with文は覚えておいて損はないと思います。
今回はnew.html.erbで作ったユーザで実際にログインするためのページを作成していきます。
〇Model、Controller、Router、Viewの作成【new(session)】
これまでは、Userフォルダ内に作られたindex、show、newを編集してそれぞれのページを作りました。
ただ、今回のログインページは少し作る場所が異なるのが注意です。
ログインページは、Sessionというシステムを使います。
このSessionは、「ユーザのログイン、ログアウトを管理するRailsのシステム」です。
難しい話は省略しますが、ログインした際のログイン情報を保管しておく場所で、
これがログインの担保となる、といったイメージでしょうか。
正直、「ログインに関するものはSessionで扱う」と覚えておくだけで問題ないかと思います(笑)。
MCRV(Model、Controller、Router、View)もこれまでと少し違うので、少しゆっくり進んでいきましょう!
・Model
SessionのModelは作成不要となっています。
ログイン情報を保管する場所はRailsにデフォルトであるようです。
・Controller
これまでToppageやUserについてControllerを作ってきましたが、
同様にSessionについてもControllerを作る必要があります。
以下のコードをターミナルに打ち込んでSessionについてのControllerを作っちゃいます。
1 |
rails generate controller sessions new create destroy |
「Railsで、new、create、destroyのメソッドを持ったSessions_controllerを作成する」ですね!
new、create、destroyそれぞれの役割は後で説明します。
これで、sessions_controller.rbとnew、create、destroyのviewファイルが作成されます。


それではsessions_controller.rbを開いてcontrollerの編集をしていきます!
開くと以下のようになっているはずです。
1 2 3 4 5 6 7 8 9 10 |
class SessionsController < ApplicationController def new end def create end def destroy end end |
ここで、new、create、destroyの役割を書いておきます。
newは、「ログインページ」を指します。
「新しくログイン情報を入力する画面=ログイン画面」という認識でしょう。
createは、ログインの動作を指します。
ログインページではだいたい、情報を入力した後にログインボタンを押してログインを行います。
このログインボタンを押した際に動作するメソッドが、createです。
これによりSessionのシステムにログイン情報が保存されます。
destroyは、ログアウトのことです。
Sessionのシステム上で残っているログイン情報を消去することで、ログアウトを行います。
こちらもよくマイページからボタンクリックで動作するメソッドとなっています。
今回はログアウトはとりあえず置いといて、newとcreateを作ります。
controllerは以下のように書きました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
class SessionsController < ApplicationController def new end def create email = params[:session][:email] password = params[:session][:password] if login(email, password) flash[:success] = 'ログインに成功しました。' redirect_to root_url else flash.now[:danger] = 'ログインに失敗しました。' render :new end end def destroy session[:user_id] = nil flash[:success] = 'ログアウトしました。' redirect_to root_url end private def login(email, password) @user = User.find_by(email: email) if @user && @user.authenticate(password) # ログイン成功 session[:user_id] = @user.id return true else # ログイン失敗 return false end end end |
かなり長くなってしまいましたが、基本コピペで構いません!(笑)
気になったところは調べてもらえればと思います。
重要なことだけ書こうと思いますが、
Viewを見ながらの方がわかりやすいので、とりあえず先に進みます。
・Router
Routerについては、Controllerで作ったsessionのnew、create、destroyのルーティングが必要です。
Routerはroutes.rbが管理していますが、僕は以下の文を追記することでルーティングを行いました。
1 |
resources :sessions, only: [:new, :create, :destroy] |
resoucesについては以前userの記事で説明しましたが、
「resouces :○○」と記述することで、7つのメソッドをすべてルーティングできるという仕組みでした。
ただし、今回は7つのメソッドのうちnew、create、destroyのみ使います。
このような場合に、「resouces :○○」の後に、「only: [○○、△△]」と追記することで
必要なもののみルーティングすることもできます。
これでRouterも設定できたので、あとはViewです!
・View
ログインページのViewファイルは、先ほど作成したsessionのnew.html.erbです。
僕は以下のようにしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<div class="text-center"> <h1>ログイン</h1> </div> <div class="row"> <div class="col-sm-6 offset-sm-3"> <%= form_with(url: new_session_path, scope: :session, local: true) do |f| %> <div class="form-group"> <%= f.label :email, 'Email' %> <%= f.email_field :email, class: 'form-control' %> </div> <div class="form-group"> <%= f.label :password, 'パスワード' %> <%= f.password_field :password, class: 'form-control' %> </div> <%= f.submit 'Log in', class: 'btn btn-primary btn-block' %> <% end %> <p><%= link_to '新規登録', new_user_path %></p> </div> </div> |
ページの上部に「ログイン」の文字を置いています。
その後は、新規登録画面と同様にform_with文を使ってログインフォームを作成しています。
ログインの場合はフォームの入力情報をSessionに送る必要があるので、スコープ機能を使っています。
ちなみに最後の行に、登録していない人のために新規登録へのページのリンクを作っています。
「link_to ‘文字列’, ページのパス」でリンクを作ることができます。
今回はメールアドレスとパスワードをログイン情報としています。
さて、Viewもできたので先ほど放置していたControllerの説明をしちゃいます!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
class SessionsController < ApplicationController def new end def create email = params[:session][:email] password = params[:session][:password] if login(email, password) flash[:success] = 'ログインに成功しました。' redirect_to root_url else flash.now[:danger] = 'ログインに失敗しました。' render :new end end def destroy session[:user_id] = nil flash[:success] = 'ログアウトしました。' redirect_to root_url end private def login(email, password) @user = User.find_by(email: email) if @user && @user.authenticate(password) # ログイン成功 session[:user_id] = @user.id return true else # ログイン失敗 return false end end end |
newは特に何もないので、コニカ委はフォームを使ってログインボタンを押した際に動作するcreateメソッドについてのみ説明します。
(今回はログアウトは扱わないので、destroyは割愛で。)
new.html.erbで入力したemailとpasswordはフォームとしてSessionに送られます。
基本的にアプリのユーザが入力したものはそれぞれのparamsに送られます。
ただ普通にユーザが入力した情報はアプリのparamsに送られるのですが、今回はSessionという別のシステムに送りました。
なので、その情報を参照するには、「Sessionのparamsの○○」というように指定する必要があります。
それを踏まえると、以下の2文
1 2 |
email = params[:session][:email] password = params[:session][:password] |
これは、
「変数emailにSessionのparamsのemailの項目を代入」
「変数passwordにSessionのparamsのpasswordの項目を代入」
となります。
これにより、ユーザが入力し送信したemail、passwordを扱えます。
この次に、
1 |
if login(email, password) |
とあります。
「なんじゃこりゃ」となるかもしれませんが、落ち着いて下の方を見ましょう。
「private」と書かれている一文があり、その下で
「def login()」と定義がされています。
この下の文でログインを関数として定義しています。
この文は少し難しいのですが、この2文が肝。
1 2 |
@user = User.find_by(email: email) if @user && @user.authenticate(password) |
どういう流れになっているかというと、
①UserのModelから、email項目が変数email(こっちはさっきparamsを使って代入したやつ)と一致するものを探し、インスタンス変数@userに代入する。
②@userのパスワードがparamsで入力したパスワードと一致しているか確認
という流れになっています。
これにより、ログイン情報が正しいか検証しているんですね!
さて上のcreateメソッドに戻ります。
こちらの定義したloginメソッドを使ってログイン情報が正しいか検証し、
正しい場合と誤りがある場合で条件分岐させflashでフラッシュメッセージを適用させています。
(フラッシュメッセージについては次回の記事で扱います)
これでMCRVすべてそろいました!
〇ファイルの確認
それではログインページに飛んでみてみましょう。
今回はURLの末尾に「sessions/new」をつけます。
以下のようなページになっているのではないでしょうか!

なっていれば成功です!
〇次回 ~ナビバーとフラッシュメッセージの設定~
今回はここまでです!
ここまでいくつかのページを作ってきましたが、ページの体裁にはほとんどこだわらず作ってきました!(笑)
なので、次回はちょっとWebアプリっぽくするために、
ナビバーの設定とフラッシュメッセージ、エラーメッセージの適用を行います。
本シリーズでまろんぼーいが実際に作成中のアプリについては、以下のURLで公開しています。
各viewページを直接確認する場合は、本記事と同様のURLを末尾につければ飛ぶことができます。
ご参考までに!
今回もご覧いただきありがとうございました!