rails ユーザー管理

今回はrailsのユーザー周りについて書こうと思います。

# 目次
まず基本となる、ユーザー周りの設定

1.deviseのインストール
2.Userモデルを作成する
3.deviseのビューファイルの作成
4.サインアップ機能の追加
5.ユーザー情報編集機能の追加
6.ログアウト機能の追加
7.フラッシュメッセージの表示機能の実装

## 1.deviseのインストール

```ruby:gemfile
gem 'devise'
```

```bash:ターミナル
$ bundle install
$ rails g devise:install
```


## 2.Userモデルを作成する

```bash:ターミナル
$ rails g devise user
```
deviseで使用するモデルは、rails g devise <モデル名>コマンドで作成できます。

```ruby:マイグレーションファイル
class DeviseCreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :name,               null: false, unique: true, index: true
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""
# 〜省略〜
```

```bash:ターミナル
$ rails db:migrate
```

###gemfileの注意
group内に記述するとそこしか機能しかしなくなるので
注意すること

```ruby:gemfile
group :development do
  gem 'devise'
end
```

### マイグレーションファイルの誤りがあった場合
下記のコマンドでやり直します。

```bahs:ターミナル
rails db:rollback
```

## 3.deviseのビューファイルの作成
①app/viewsフォルダに「devise」および「users」フォルダを作成とhtml(haml)ファイルを作成します

②app/assets/stylesheets/modulesに「user.scss」のファイルを作成

③application.scssにファイルの参照を記述

```scss:app/assets/stylesheets/application.scss
@import "modules/user";
```


## 4.サインアップ機能の追加

サインアップ時に、ユーザーの名前を登録できるようapplication_controller.rbを編集します。
具体内容はこちらを見て下さい
[rails 発展その2 ログイン機能](https://qiita.com/savaniased/items/a7ee3cf1cd6dab4755e0#devise%E7%94%A8%E3%81%AE%E3%82%B9%E3%83%88%E3%83%AD%E3%83%B3%E3%82%B0%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%83%BC%E8%A8%AD%E5%AE%9A)

```ruby:application_controller.rb
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
```

## 5.ユーザー情報編集機能の追加

```bash:ターミナル
$ rails g controller users
```

編集画面のビューを作成します。

```haml:app/views/users/edit.html.haml
#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'
```
次にこの機能を追加します。
・ユーザー情報の更新が正常にできる
・画面左上に、ログイン中のユーザー名が表示される
・歯車のアイコンをクリックすると、作成した編集ページに遷移する。

```ruby:routes.rb
# ルーティングを追加
Rails.application.routes.draw do
  devise_for :users
  root 'messages#index'
  resources :users, only: [:edit, :update] # editとupdateのパスを作成
end
```

```ruby:users_controller.rb
class UsersController < ApplicationController

  def edit # editのコントローラを作成
  end

  def update # updateのコントローラの作成
    if current_user.update(user_params)
      redirect_to root_path # 編集できたらルートパスに帰る
    else
      render :edit # ユーザーでなかったらeditに戻る
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email)
  end
end
```

```haml:shared/_side_bar.html.haml
/ ユーザー編集ページに遷移するためのパスを追加
.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
        新着メッセージ
```

## 6.ログアウト機能の追加

```haml:users/edit.html.haml
#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'
     // ~省略~
```

「rake routes」コマンドを実行すると
どのようなリンク先を指定すれば、該当のアクションが動くのか確認できます。

```bash:ターミナル
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.フラッシュメッセージの表示機能の実装

フラッシュメッセージとは
アクションの実行後に簡単なメッセージを表示するRailsの機能です。

フラッシュメッセージ実装の手順
フラッシュメッセージは、デフォルトでは英語で表示されます。以下のステップで実装していく中で、メッセージの日本語化も行いましょう。

①フラッシュメッセージが表示されるようにする
②フラッシュメッセージのスタイリングを行う
③フラッシュメッセージを日本語化する

### ①フラッシュメッセージが表示されるようにする

メッセージ用のビューを追加

```haml:app/views/layouts/_notifications.html.haml
.notification
  - flash.each do |key, value|
    = content_tag :div, value, class: key
```

1.flashオブジェクトの使い方
deviseを使用すると、ログイン時などに表示させるメッセージが「flashオブジェクト」に自動で格納されます。

flashオブジェクト内には、複数のメッセージがハッシュのように「キー」「バリュー」形式で保存されています。

each文を使うと、これらを1つずつ取り出すことができ
ChatSpaceでは「キー」を「CSS用のクラス名」に、「バリュー」を「表示するメッセージ本文」として使っています。

2.フラッシュメッセージが表示されるようにしよう
続いて、上記のビューが表示されるよう設定します。

```haml:app/views/layouts/application.html.haml
!!!
%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
```


### ②フラッシュメッセージのスタイリングを行う
フラッシュメッセージのデザインを行うため、scssファイルを追加していきましょう。

1.「stylesheets/config」フォルダに、「colors.scss」という名称でファイルを作りましょう。
作成したら、以下のコードを記述します。

```scss:stylesheets/config/colors.scss
$white: #fff;
$side_blue_dark: #253141;
$side_blue_light: #2f3e51;
$light_blue: #38AEF0;
$light_gray: #999;
$black: #434a54;
$alert_orange: #F35500;
```

2.続いて、「stylesheets/modules」フォルダに「flash.scss」を作成し設定を行います。
「通知用」のメッセージと「アラート用」メッセージでスタイルを分けています。

```scss:stylesheets/modules/flash.scss
.notification {
  .notice {
    background-color: $light_blue;
    color: $white;
    text-align: center;
  }

  .alert {
    background-color: $alert_orange;
    color: $white;
    text-align: center;
  }
}
```

3.最後にapplication.scssを編集して、作成した設定ファイルが読み込まれるようにしましょう。

```scss:application.scss
// colors.scssとflash.scssをインポート
@import "config/colors";
@import "modules/flash";
```

### ③フラッシュメッセージを日本語化する

1.日本語化用のファイルを作成しよう

「config/locales」フォルダに、「devise.ja.yml」および「ja.yml」という名前のファイルを新規作成します。

下記のサイトに記述内容が掲載されているので、それぞれ中身を丸ごとコピーして貼り付け、保存しましょう。

* [devise.ja.yml](https://github.com/tigrish/devise-i18n/blob/master/rails/locales/ja.yml)
* [ja.yml](https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml)

2.日本語化のための設定を行おう

```ruby:config/application.rb
module ChatSpace
  class Application < Rails::Application
    #〜省略〜
    config.i18n.default_locale = :ja
  end
end
```

### colors.scssの読み込みの順番について
colors.scssは、reset.scssの直後で読み込むようにしましょう。

colors.scssには、他のscssで利用している色についての変数が定義されています。
そのため、色についての変数を利用するCSSの前に先に読み込めていないと、エラーになってしまいます。