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