ユーザー管理実装
ユーザー管理実装のステップ
ユーザー管理機能を以下のステップで実装する。
- deviseのインストール
- Userモデルを作成する
- deviseのビューファイルの追加
- サインアップ機能の追加
- ユーザー情報編集機能の追加
- ログアウト機能の追加
- フラッシュメッセージの表示機能の実装
1. deviseのインストール
ユーザー管理機能を実装に、「devise」を使用する。
最初にインストールを行う。
Gemfileに追加
Gemをインストールするため、Gemfileに追記。
下記の説明を参考に、記述する場所に注意。
1 2 3 |
(前略)
gem 'devise'
(後略)
|
以下のように、group内に記述すると特定の環境でのみ使用する設定になってしまう。deviseは開発、テスト、本番いずれの環境でも使用するので注意。
NG例
1 2 3 |
group :development do
gem 'devise'
end
|
この記述だとdevelopment環境から、テストや本番環境に移行していくので、その際に対応できなくなってしまう。
deviseのインストールを行う
続いてGemおよびdeviseのインストールを行う。deviseの場合は、bundle installの他にdevise用のインストールコマンドの実行が必要なので注意。
1 2 |
$ bundle install
$ rails g devise:install
|
2. Userモデルを作成
ユーザーを管理するためのモデルファイルや、テーブルを作成する。
以下の点に注意して、実装する。
・deviseで使用するモデルを作成するときは、rails g modelのような通常のモデル作成とはコマンドが異なる。
・どのようなカラムを追加するか、カラムにどのような制約をかけるか事前にDB設計を確認。
問題1:devise用のUserモデルを作成。追加するカラムに気をつけ、マイグレートまで行う
1 |
$ rails g devise user
|
1 2 3 4 5 6 7 8 9 10 11 |
class DeviseCreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
## Database authenticatable
t.string :name, null: false
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
end
add_index :users, :name, unique: true
# 〜省略〜
|
1 2 3 4 5 6 7 8 9 |
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
validates :name, presence: true
end
|
解説
deviseで使用するモデルは、rails g devise <モデル名>
コマンドで作成できる。
ターミナル上でrails g devise User
を実行し、Userモデルを作成。
作成されたマイグレーションファイルを開き、t.string :name, null: false と add_index :users, :name, unique: trueを上記の様に追記。これで、マイグレーション実行時にnameカラムがNOT NULL制約・一意性制約付きで作成される。
NOT NULL制約では空の文字列は保存可能なため、validatesを使用。
更にuser.rb に validates :name, presence: trueと追記し、空の文字列の場合もエラーが発生する様にする。
最後にマイグレーションを実行。
1 |
$ rails db:migrate
|
コマンドを誤った場合の対応方法
誤ったコマンドを実行してしまった場合は、以下を参考に修正を行う。
rails gコマンドの誤り
rails g model userコマンドでファイルを作ってしまった場合は、下記のコマンドを実行してファイルの削除を行う。
1 |
rails d model user
|
マイグレーションファイルの誤り
マイグレーションファイルの記述を誤ったままマイグレートしてしまった場合は、下記のコマンドを実行してからもう一度やり直し。
1 |
rails db:rollback
|
3. deviseのビューファイルの設定
deviese用のスタイリングを行う。
問題2:ファイルを配置する
①「devise」および「users」フォルダをapp/views
フォルダに配置する。
②「user.scss」のファイルをapp/assets/stylesheets/modules
に配置する。
③下記のファイルを変更する。
1 2 3 4 5 |
解説
ファイルが読み込まれるようapplication.scssにimport文を追加。
4. サインアップ機能の追加
deviseのデフォルトの機能では、「メールアドレス」および「パスワード」を入力してユーザー登録を行う。ChatSpaceでは「名前」も合わせてサインアップする仕様となっている。
ユーザー登録フォームのビューは、すでにダウンロードしたファイルであれば実装済み。そのほか、保存に必要な機能を実装する。
application_controller.rbを編集
サインアップ時に、ユーザーの名前を登録できるようapplication_controller.rbを編集。
1 2 3 4 5 6 7 8 9 10 11 |
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
end
end
|
Railsでは、悪意のあるユーザーの入力に対してセキュリティ対策を行わないと保存できない仕組みがある。
通常のテーブルに保存する際はストロングパラメータを使用したが、deviseを使ったモデルの場合は方法が異なる。
上のコードは、deviseの公式サイトで紹介されている書き方。そのまま使用するものという理解でも問題ない。
4 |
before_action :configure_permitted_parameters, if: :devise_controller?
|
application_controllerにbefore_actionを使用しているため、全てのアクションが実行される前に、この部分が実行されることになる。deviseのコントローラーから呼び出された場合は、「configure_permitted_parameters」メソッドが呼ばれる。
8 9 10 |
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
end
|
ここでconfigure_permitted_parametersの定義を行なっている。
deviseをインストールすることでdevise_parameter_sanitizerのpermitメソッドが使えるようになるが、これがストロングパラメータに該当する機能。サインアップ時に入力された「name」キーの内容の保存を許可している。
設定が終わったら、以下のURLにアクセスして正常にビューが表示されることを確認。
http://localhost:3000/users/sign_up
ビューが確認できたら、そのままアカウントを作成してログイン状態にしておく。
5. ユーザー情報編集機能の追加
登録済みのユーザー情報を編集できるよう機能を追加。
ユーザーの名前とメールアドレスを変更できるようにする。
コントローラーを作成
まず編集機能の実装に必要なUsersコントローラーを作成。
1 |
$ rails g controller users
|
編集画面のビューを作成
ユーザー情報の編集用のビューを作成。
サインアップ時の画面と似たデザインで実装する。
①app/views/usersフォルダにファイルを新規作成し、「edit.html.haml」と名前をつける。
②①のファイルを以下の内容に編集。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#account-page.account-page
.account-page__inner.clearfix
.account-page__inner--left.account-page__header
%h2 Edit Account
%h5 アカウントの編集
%i.btn ログアウト
= link_to "トップページに戻る", :back, class: 'btn'
.account-page__inner--right.user-form
= form_for(current_user) do |f|
.field
.field-label
= f.label :name
.field-input
= f.text_field :name, autofocus: true
.field
.field-label
= f.label :email
.field-input
= f.email_field :email
.actions
= f.submit "Update", class: 'btn'
|
ここまでで、コントローラーとビューを作成したが、編集機能の実装には他にも必要な手順がある。
問題3:ユーザー情報編集機能を実装する
・ユーザー情報の更新が正常にできるようにする・画面左上に、ログイン中のユーザー名が表示される
・歯車のアイコンをクリックすると、作成した編集ページに遷移する
1 2 3 4 5 6 7 8 9 |
# ルーティングを追加
Rails.application.routes.draw do
devise_for :users
# 下の行は削除する
# get 'messages/index
root "messages#index"
resources :users, only: [:edit, :update]
end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class UsersController < ApplicationController
def edit
end
def update
if current_user.update(user_params)
redirect_to root_path
else
render :edit
end
end
private
def user_params
params.require(:user).permit(:name, :email)
end
end
|
下記の_side_bar.html.hamlのコードは一例。
自身のコードと読み替えて、必要な追記を行う。
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 |
/ ユーザー編集ページに遷移するためのパスを追加
.side-bar
.header
%h3.header__name
= current_user.name
%ul.header__lists
%li.list
= link_to do
= icon('fas', 'pen-square', class: 'icon')
%li.list
= link_to edit_user_path(current_user) do
= icon('fas', 'cog', class: 'icon')
.groups
.group
.group__name
グループ名
.group__message
新着メッセージ
.group
.group__name
グループ名
.group__message
新着メッセージ
.group
.group__name
グループ名
.group__message
新着メッセージ
|
解説
ユーザー編集機能を実装するため、まずはルーティングを定義。
ユーザーの編集に必要なルーティングは:edit
, :update
なので、routes.rbに追記。
次に、ルーティングに対応するコントローラのアクションを定義。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class UsersController < ApplicationController
def edit
end
def update
if current_user.update(user_params)
redirect_to root_path
else
render :edit
end
end
private
def user_params
params.require(:user).permit(:name, :email)
end
end
|
edit
アクションでは必要になるインスタンス変数はないので、アクションを定義するだけで大丈夫。
Userモデルの更新を行うupdate
アクションは、保存できた場合、できなかった場合で処理を分岐。
updateできた場合は「true」が、できなかった場合は「false」が返り値として戻ってくる。それを利用して、if文での分岐ができる。
今回の場合は、current_user.updateに成功した場合、rootにリダイレクトし、失敗した場合、edit
のビューを再度描画する、という記述になっている。
6. ログアウト機能の追加
現在は、ユーザーの編集画面に「ログアウト」という文字だけが表示されている。
ログアウトをクリックしたら、実際にログアウトされるよう実装する。
問題4:ログアウト機能を実装する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#account-page.account-page
.account-page__inner.clearfix
.account-page__inner--left.account-page__header
%h2 Edit Account
%h5 アカウントの編集
= link_to "ログアウト", destroy_user_session_path, method: :delete, class: 'btn'
= link_to "トップページに戻る", :back, class: 'btn'
.account-page__inner--right.user-form
= form_for(current_user) do |f|
.field
.field-label
= f.label :name
.field-input
= f.text_field :name, autofocus: true
.field
.field-label
= f.label :email
.field-input
= f.email_field :email
.actions
= f.submit "Update", class: 'btn'
|
解説
「rake routes」コマンドを実行すると、どのようなリンク先を指定すれば、該当のアクションが動くのか確認できる。
1 |
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
|
該当部分はこのような結果になる。
prefix: 「destroy_user_session_path」
HTTPメソッド: 「DELETE」
を指定すると、sessionsコントローラーのdestroyアクションが実行されることがわかる。
これを、link_toの引数として使用する。
なお、「btn」というクラスはCSSを適用させるためのもの。
7. フラッシュメッセージの表示機能の実装
ChatSpaceにメッセージ表示機能を追加する。
ユーザーが、「サインアップ」「ログイン」「ログアウト」を行った直後にメッセージが出るようにする。
フラッシュメッセージとは
アクションの実行後に簡単なメッセージを表示するRailsの機能。
今回はdeviseの認証関係のメッセージとして使用しますが、その他任意のテキストを表示するためにも使える。
フラッシュメッセージ実装の手順
フラッシュメッセージは、デフォルトでは英語で表示される。以下のステップで実装していく中で、メッセージの日本語化も行う。
①フラッシュメッセージが表示されるようにする
②フラッシュメッセージのスタイリングを行う
③フラッシュメッセージを日本語化する
サインアップ時のフラッシュメッセージ
サインイン時のフラッシュメッセージ
ログアウト時のフラッシュメッセージ
7-1 フラッシュメッセージが表示されるようにする
まずは、メッセージが表示されるまでの実装を行う。
メッセージ用のビューを追加
まず、フラッシュメッセージを表示するためのビューを作成。
「views/layouts」フォルダの中に、「_notifications.html.haml」と名称で新規作成する。そのファイルに、以下の記述を行う。
1 2 3 |
flashオブジェクトの使い方
deviseを使用すると、ログイン時などに表示させるメッセージが「flashオブジェクト」に自動で格納される。
flashオブジェクト内には、複数のメッセージがハッシュのように「キー」「バリュー」形式で保存されている。
each文を使うと、これらを1つずつ取り出すことができ、ChatSpaceでは「キー」を「CSS用のクラス名」に、「バリュー」を「表示するメッセージ本文」として使っている。
フラッシュメッセージが表示されるようにする
続いて、上記のビューが表示されるよう設定。
application.html.hamlに記述を追加する。
1 2 3 4 5 6 7 8 9 10 11 |
!!!
%html
%head
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
%title ChatSpace
= csrf_meta_tags
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_include_tag 'application', 'data-turbolinks-track': 'reload'
%body
= render 'layouts/notifications'
= yield
|
この記述によって、フラッシュメッセージが表示されるようになるが、どのような仕組みで表示がされるのか確認する。
今追記を行なった「application.html.haml」は、どのビューを表示するときも必ず表示されるようデフォルトで設定されているファイル。
このファイルの11行目に「yield」と記述があることに注目。
このyieldは、ビューファイルの内容をここに埋め込むために使われている。
例えば、コントローラーのindexアクションが実行され、「index.html.haml」が表示される場面を考える。
まず、「application.html」に書かれた内容は全て表示される。その上で、yieldの部分に「index.html」の内容が埋め込まれ表示される。
この動作によって、indexのビューの上部にフラッシュメッセージが表示されることになる。
実際にログアウトなどを実行し、正しく表示されることを確認する。
続いて、このメッセージのデザインを整えていく。
7-2 フラッシュメッセージのスタイリングを行う
フラッシュメッセージのデザインを行うため、scssファイルを追加。
flash.scssを作成
「stylesheets/config」フォルダに、「colors.scss」という名称でファイルを作り、作成したら、以下のコードを記述。
1 2 3 4 5 6 7 |
$white: #fff;
$side_blue_dark: #253141;
$side_blue_light: #2f3e51;
$light_blue: #38AEF0;
$light_gray: #999;
$black: #434a54;
$alert_orange: #F35500;
|
続いて、「stylesheets/modules」フォルダに「flash.scss」を作成し設定を行う。「通知用」のメッセージと「アラート用」メッセージでスタイルを分けている。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
.notification {
.notice {
background-color: $light_blue;
color: $white;
text-align: center;
}
.alert {
background-color: $alert_orange;
color: $white;
text-align: center;
}
}
|
最後にapplication.scssを編集して、作成した設定ファイルが読み込まれるようにする。
1 2 3 4 5 6 7 |
colors.scssの読み込みの順番について
colors.scssは、reset.scssの直後で読み込むようにする。
colors.scssには、他のscssで利用している色についての変数が定義されている。
そのため、色についての変数を利用するCSSの前に先に読み込めていないと、エラーになってしまう。
7-3 フラッシュメッセージを日本語化する
日本語化用のファイルを作成する
「config/locales」フォルダに、「devise.ja.yml」および「ja.yml」という名前のファイルを新規作成。
下記のサイトに記述内容が掲載されているので、それぞれ中身を丸ごとコピーして貼り付け、保存。
- devise.ja.ymlhttps://github.com/tigrish/devise-i18n/blob/master/rails/locales/ja.yml
- ja.ymlhttps://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml
日本語化のための設定を行う
application.rbを編集して、言語設定を変更する。
1 2 3 4 5 6 |
表示を確認する
ここまでの設定が終わったら、仮想サーバーを再起動して正しく日本語でフラッシュメッセージの表示がされることを確認。