【Ruby on Rails】簡単なメモアプリの作成|ユーザー認証と併せてユーザー機能を実装
開発環境
- Ruby:version 3.1.2
- Ruby on Rails:version 7.0.4
- Visual Studio Code:version 1.73.0
- OS:Windows10
Ruby on Railsでユーザー機能の実装手順
Ruby on Railsではユーザー認証と併せてユーザー機能を実装することにより、ユーザーフレンドリーなWebサービスを提供しやすくなります。 今回はメモアプリの作成で使用したgemのdeviseなしで自作したログイン機能を用いた「ユーザー機能」のコードを用いて解説していきます。
ユーザー機能のユーザーモデルの作成
まずはログイン機能で使用するユーザーモデルを作成します。
1rails g model User
次にユーザーモデルのマイグレーションファイルに必要な「名前、メールアドレス、パスワード」のカラムを追加していきます。
1# memo_app\db\migrate\20230108041355_create_users.rb 2class CreateUsers < ActiveRecord::Migration[7.0] 3 def change 4 create_table :users do |t| 5+ t.string :name 6+ t.string :email 7+ t.string :password 8 t.timestamps 9 end 10 end 11end
上記の記述が完了したら、以下のコマンドを叩いてマイグレーションファイルを反映させます。
1rails db:migrate
ユーザーモデルのカラムにそれぞれバリデーションを設定していきます。
1# memo_app\app\models\user.rb 2class User < ApplicationRecord 3+ validates :name, presence: true, length: {minimum:2, maximum:32} 4+ validates :email, presence: true, uniqueness: true 5+ validates :password, presence: true, format: {with: /^[0-9a-zA-Z]+$/, multiline: true} 6end
今回は簡易的になりますが、パスワードのカラムに正規表現を使用して半角英数字(英字は大文字も許可)にしています。
ユーザー機能のルーティングの作成
次にユーザー機能のルーティングを作成していきます。
1# memo_app/config/routes.rb 2 3Rails.application.routes.draw do 4 root :to => 'memos#index' 5+ resource :users, only: [:new, :show, :edit, :create, :update] 6 get 'login', to: 'sessions#new', as: 'new_sessions' 7 post 'login', to: 'sessions#create', as: 'create_sessions' 8 delete 'logout', to: 'sessions#destroy', as: 'destroy_sessions'
今回はshowやeditのアクションでは、URLに:idを含めないようにするため、resourceとしているのがポイントです。
ユーザー機能のコントローラーの作成
次にユーザー機能のコントローラーを作成していきます。
1rails g controller users
コントローラーの作成が完了しましたら、それぞれのアクションに必要な処理を記述していきます。
1# memo_app/app/controllers/users_controller.rb 2class UsersController < ApplicationController 3 4+ def new 5+ @user_new = User.new 6+ end 7+ 8+ def show 9+ @user = User.find(session[:user_id]) 10+ end 11+ 12+ def edit 13+ @user = User.find(session[:user_id]) 14+ end 15+ 16+ def create 17+ @user_new = User.new(user_params) 18+ if @user_new.save 19+ session[:user_id] = @user_new.id 20+ flash.now[:notice] = "ユーザーの新規登録に成功しました。" 21+ redirect_to memos_path 22+ else 23+ flash.now[:alert] = "ユーザーの新規登録に失敗しました。" 24+ render action: "new" 25+ end 26+ end 27+ 28+ def update 29+ @user = User.find(session[:user_id]) 30+ if @user.update(user_params) 31+ redirect_to users_path 32+ flash.now[:notice] = "ユーザー情報の更新に成功しました。" 33+ else 34+ render action: "edit" 35+ flash.now[:alert] = "ユーザー情報の更新に失敗しました。" 36+ end 37+ end 38+ 39+ private 40+ 41+ def user_params 42+ params.require(:user).permit(:name, :email, :password) 43+ end 44 45end
特にユーザー機能ではストロングパラメーターの仕組みを利用するのが推奨されています。 そのため、ユーザー情報のパラメーターを取得する取得するメソッドをユーザーコントローラー内のprivate内にuser_paramsというメソッド名で作成しています。 また、ユーザー登録と同時にsessionメソッドでユーザーのクッキーにユーザーIDを渡すことにより、ユーザー登録と同時にログイン状態にすることができます。
ユーザー機能のユーザー登録画面の作成
次にユーザー機能のユーザー登録画面の作成をしています。
1# memo_app/app/views/users/new.html.erb 2<div class="wrapper"> 3 <div class="container"> 4 <h2>ユーザー新規登録</h2> 5 6 <%= form_with model: @user_new, url: users_path, local: true, method: :post do |f| %> 7 <%= f.label :name, "Name" %> 8 <%= f.text_field :name, class: "form-box" %> 9 10 <%= f.label :email, "Email" %> 11 <%= f.email_field :email, class: "form-box" %> 12 13 <%= f.label :password, "Password" %> 14 <%= f.password_field :password, class: "form-box" %> 15 16 <%= f.submit "新規登録", class: "btn" %> 17 <% end %> 18 </div> 19</div>
ユーザー登録機能に必要なユーザー名、メールアドレス、パスワードを登録するフォームを作成しています。
ユーザー機能のユーザー詳細画面の作成
次にユーザー機能のユーザー詳細画面の作成をしています。
1# memo_app/app/views/users/show.html.erb 2<div class="wrapper"> 3 <div class="container"> 4 <h2>ユーザー情報</h2> 5 6 <div class=""> 7 <p>Name</p> 8 </div> 9 <div class="form-box"> 10 <%= @user.name %> 11 </div> 12 13 <div class=""> 14 <p>Email</p> 15 </div> 16 <div class="form-box"> 17 <%= @user.email %> 18 </div> 19 20 <%= link_to "編集", edit_users_path, method: :get %> 21 22 </div> 23</div>
ユーザー情報を表示する場合、パスワードなどの機密情報の取り扱いには注意する必要があります。 そのため、ユーザー詳細ページではパスワードは表示しないようにしています。
ユーザー機能のユーザー編集画面の作成
次にユーザー機能のユーザー編集画面の作成をしています。
1# memo_app/app/views/users/edit.html.erb 2<div class="wrapper"> 3 <div class="container"> 4 <h2>ユーザー編集</h2> 5 6 <%= form_with model: @user, url: users_path, local: true, method: :patch do |f| %> 7 <%= f.label :name, "Name" %> 8 <%= f.text_field :name, class: "form-box" %> 9 10 <%= f.label :email, "Email" %> 11 <%= f.email_field :email, class: "form-box" %> 12 13 <%= f.submit "更新", class: "btn" %> 14 <% end %> 15 </div> 16</div>
ユーザー情報を編集する場合、同じようにパスワードなどの機密情報の取り扱いには注意する必要があります。 もし、パスワードを変更する場合の機能を実装したい場合は、様々なWebアプリケーションと同様に処理を分けてあげたほうが良いかと思います。
ユーザー機能への導線の作成
次にユーザー機能への導線を作成しています。
1# memo_app/app/views/layouts/application.html.erb 2 3 <div class="header-right"> 4+ <% if @current_user.nil? %> 5+ <%= link_to "新規登録", new_users_path, method: :get %> 6 <%= link_to "ログイン", new_sessions_path, method: :get %> 7 <% else %> 8+ ログインユーザー:<%= @current_user.name %>さん 9+ <%= link_to "登録情報", users_path, method: :get %> 10 <%= link_to "ログアウト", destroy_sessions_path, method: :delete %> 11 <% end %> 12 </div>
もしユーザーがログイン状態であれば登録情報画面へのリンク、ログアウト状態であれば新規登録画面へのリンクを追加しています。
ユーザー機能のユーザー認証の整理
次にユーザー機能のユーザー認証の整理しています。
1# memo_app/app/controllers/application_controller.rb 2class ApplicationController < ActionController::Base 3 4 def current_user 5 if session[:user_id] 6 @current_user = User.find(session[:user_id]) 7 else 8 flash[:alert] = "ログインする必要があります。" 9 redirect_to new_sessions_path 10 end 11 end 12 13 def logged_in? 14 if session[:user_id] 15 @current_user = User.find(session[:user_id]) 16 flash[:notice] = "すでにログインしています。" 17 redirect_to memos_path 18 end 19 end 20 21end
また、今回はユーザー機能を実装したことにより、変数が重複してしまうことが多くなるため、わかりやすいように変数を「@current_user」に修正しています。 同じように「app/controllers/sessions_controller.rb」や「app/views/sessions/new.html.erb」の変数も修正しておきましょう。
ユーザー機能にアクセス制限を実装
次にユーザー機能にアクセス制限を実装しています。
1# memo_app/app/controllers/users_controller.rb 2class UsersController < ApplicationController 3+ before_action :current_user, only: [:show, :edit, :update] 4+ before_action :logged_in?, only: [:new, :create] 5 6 def new 7 @user_new = User.new 8 end
ユーザーがログインしていない状態でユーザー情報の閲覧、編集や更新をされては非常に危ないため、ユーザーコントローラーの「show,edit,update」に「current_user」でアクセス制限をかけています。 また、ユーザーはログイン状態ではユーザー登録ができないようにするため、ユーザーコントローラーの「new,create」に「logged_in?」でアクセス制限をかけています。
おわりに
Ruby on Railsで自作ログイン機能を用いたユーザー機能の実装について解説してきましたが、いかがだったでしょうか。 ユーザー管理は非常に重要な機能なため、今回は省略していますがユーザー削除の機能を実装する場合も論理削除とするか、物理削除とするかもWebアプリケーションの方針に深くかかわってきます。 是非、ユーザーがWebアプリケーションを使いやすいようにするためにも、ユーザー機能の実装にチャレンジにしてみてください。