Deviseの認証とマイページを導入してみる

毎回導入時に迷子になっていたので、自分用の備忘録として残します。

# 環境
- rails (6.0.0)
- devise (4.7.1)
- devise-i18n (1.8.2)

# Devise で認証とマイページを導入してみる

#### 作業ディレクトリの用意
```bash
$ mkdir devise-demo
$ cd devise-demo/
```

#### アプリケーション作成
Rails アプリの初期設定を行う

```bash
$ bundle init
$ bundle add rails
$ bundle exec rails new . -d mysql
$ bundle
$ bundle update
$ bin/rails db:create
$ bin/rails webpacker:install
```

#### Devise 導入
Gemfile に Devise を追加

```ruby:Gemfile
# 下記を追記
gem 'devise'
gem 'devise-i18n'
```

Devise をインストール

```bash
$ bundle
```

#### Devise の初期設定

```bash
$ bin/rails g devise:install
```

```ruby:config/environments/development.rb
Rails.application.configure do
  # 以下を追記
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
```

```erb:app/views/layouts/application.html.erb
  <body>
    # 以下を追記
    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>
```

#### 認証用モデルを作成
今回は User モデルを作成

```bash
$ bin/rails g devise User
$ bin/rails db:migrate
```

#### Devise のカスタムコントローラを作成
今回は scope を auths にする

```bash
$ bin/rails g devise:controllers auths
```

`account/*` のようなパスでアクセスできるようにする

```ruby:config/routes.rb
Rails.application.routes.draw do
  # 以下を追記
  devise_for :users,
    path: 'account',
    path_names: { sign_in: :login, sign_out: :logout },
    controllers: {
      confirmations: 'auths/confirmations',
      passwords: 'auths/passwords',
      registrations: 'auths/registrations',
      sessions: 'auths/sessions'
    }
```

#### Devise のカスタムビューを作成
```bash
$ bin/rails g devise:i18n:views auths
$ bin/rails g devise:i18n:locale ja
```

```yml:config/locales/devise.views.ja.yml
   # devise: という部分を auths: に変更
   # 修正前
   devise:
   # 修正後
   auths:
```

```ruby:config/initializers/locale.rb
I18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')]
I18n.available_locales = [:ja]
I18n.default_locale = :ja
```

Rails を起動

```bash
$ bin/rails s
```

下記にアクセスすると、アカウント登録ページが表示される
http://localhost:3000/account/sign_up
<img width="799" alt="account_sign_up.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197676/cbf4ef6d-6aaf-f213-de9a-301fbaf49775.png">

#### マイページを作成

```bash
$ bin/rails g controller accounts show
```

```ruby:config/routes.rb
  resource :account, only: [:show]
```

```ruby:app/controllers/accounts_controller.rb
class AccountsController < ApplicationController
  before_action :authenticate_user!

  def show
    @account = current_user
  end
end
```

マイページのビューを作成する

```erb:app/views/accounts/show.html.erb
<h1>MyPage</h1>
<p><%= @account.email %></p>
```

Rails を起動

```bash
$ bin/rails s
```

下記にアクセスすると、マイページにアクセスできる。※ ログイン必須
http://localhost:3000/account
<img width="799" alt="account_page.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197676/eecbc094-4ba8-ef51-89f3-31e3a4706763.png">

#### ログアウト機能作成
わかりやすいように root path をマイページにする

```ruby:config/routes.rb
  root 'accounts#show'
```

ログイン/ログアウトのリンクを用意する

```erb:app/views/layouts/application.html.erb
    <% if user_signed_in? %>
      <%= link_to 'Logout', destroy_user_session_path, method: :delete %>
    <% else %>
      <%= link_to 'Login', user_session_path %>
    <% end %>
```

Rails を起動

```bash
$ bin/rails s
```

下記にアクセスすると、ログイン/ログアウトできるリンクが表示される。
http://localhost:3000/

<img width="799" alt="logout.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197676/3b5d275a-5dd9-453a-76f1-a6aeaeafc9a9.png">
<img width="799" alt="login.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197676/93d250fb-229e-a1b1-474a-c2ebd3374db8.png">
以上です。