docker-compose 下で rails new して Rails6.1+deviseを試す
TL;DR
- docker-compose のくだり以外は以下記事などとほとんど同じです
- 【Rails】deviseの使い方をマスターしてログイン認証機能を実装 | Pikawaka
- Deviseの設定手順をまとめてみた。 その1 導入編 | Qiita
今回やること、やらないこと
- やること
- docker-compose を使って Rails コンテナと MySQL コンテナを用意する
- Rails に devise を導入して email アドレスによる認証認可を構築
- devise の日本語化をする
- letter_opener_web を導入する
- ここは、以下記事と同じです
- Railsで開発環境に gem letter_opener_web を導入しメール本文をコンソールで確認するのをやめよう | 北山淳也 | zenn
- やらないこと
- devise のビューとコントローラーのカスタマイズ
- OmniAuth を導入してSNS認証などを追加する
docker-compose の準備
以下記事とほぼ同じです
- docker-compose 下で rails new して Rails6+Simpacker+Parcel 環境を作る | 北山淳也 | zenn
サクッとやっていきましょう。
cd myapp
mkdir -p forDocker/mysql/conf.d/
touch forDocker/mysql/conf.d/mysql.cnf
mkdir -p forDocker/rails/
touch forDocker/rails/entrypoint.sh
touch Dockerfile
touch docker-compose.yml
[mysqld]
default_authentication_plugin = mysql_native_password
skip-host-cache
skip-name-resolve
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init-connect = SET NAMES utf8mb4
skip-character-set-client-handshake
[client]
default-character-set = utf8mb4
[mysqldump]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /app/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
FROM ruby:2.6
RUN set -x && curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN set -x && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo 'deb http://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list
RUN set -x && apt-get update -qq && apt-get install -yq nodejs yarn vim default-mysql-client
RUN mkdir /app
WORKDIR /app
# ※ここのコメントはあとで外す
# COPY Gemfile /app/Gemfile
# COPY Gemfile.lock /app/Gemfile.lock
# RUN bundle install
COPY . /app
# Add a script to be executed every time the container starts.
COPY ./forDocker/rails/entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Start the main process.
# ※ここのコメントはあとで外す
# CMD ["rails", "server", "-b", "0.0.0.0"]
version: '3.7'
services:
app:
container_name: app
build: .
tty: true
stdin_open: true
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/app
ports:
- "3000:3000"
depends_on:
- db
db:
image: mysql:8.0
container_name: db
restart: always
volumes:
- ./forDocker/mysql/conf.d:/etc/mysql/conf.d
- dbvol:/var/lib/mysql
ports:
- "3306:3306"
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 1
TZ: "Asia/Tokyo"
volumes:
dbvol:
bundle init して rails new する
ここから先はこの後の docker-compose run --rm --service-ports app bash
で
appコンテナに入ったままコマンドを実行します
(設定ファイルの編集はvimでも、作業ディレクトリをVSCodeで開いてでもなんででも大丈夫です)
docker-compose run --rm --service-ports app bash
bundle init
Gemfile を開いて
# gem 'rails' ここを
gem 'rails', '~> 6.1.0' # こう変える
次に bundle install をします。
--path vendor/bundle
はなくても良いと思います。
--path vendor/bundle
をなくしたときは、以下のコマンドで bundle exec
としている部分は
bundle exec
なしで実行してください。
bundle install --path vendor/bundle --jobs=4
bundle exec rails new . -B -S -T -J -d mysql --force
devise のセットアップとは関係ないですが simpacker を入れておきます。
再度 Gemfile を開いて
...(前略)
group :development do
gem "simpacker" # group :development do 配下にこれを追記
...(後略)
追記したらまたコンソールに戻って
bundle install
bundle exec rails simpacker:install
...
Simpacker successfully installed 🎉 🍰
webpack も邪魔なので消しときましょう。
{
"private": true,
"devDependencies": {
}
}
またコンソールに戻って
# rails simpacker:install では npm で node_modules が入るので消して yarn する
rm -rf node_modules/
rm package-lock.json
rm webpack.config.js
yarn install
ここまで終わったら次は Rails アプリケーションの準備を整えましょう
config/database.yml を編集します。
...(前略)
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
url: mysql2://root:@db:3306
# username: root
# password:
# host: localhost
...(後略)
config/database.yml の編集を行ったら、データベースの準備をしてrailsを起動してみます。
bundle exec rails db:create
bundle exec rails db:migrate
bundle exec rails s -b "0.0.0.0"
http://localhost:3000/
でいつものアレが出ましたでしょうか。
OKですね。Ctrl+c でサーバを閉じましょう。
devise を導入する
Gemfile に以下を追加。
ついでに日本語化に必要な gem も入れちゃいましょう。
gem 'devise'
gem 'devise-i18n'
group :development do
gem 'letter_opener_web' # これも追加しときましょう。メール送信後の確認が簡単になります
end
Gemfile を編集したら appコンテナ の
ターミナルに戻って作業を進めます。
bundle install
bundle exec rails g devise:install
bundle exec rails g devise:install
すると
以下のように手作業での導入方法が表示されますね。
Running via Spring preloader in process 10589
create config/initializers/devise.rb
create config/locales/devise.en.yml
===============================================================================
Depending on your application's configuration some manual setup may be required:
1. Ensure you have defined default url options in your environments files. Here
is an example of default_url_options appropriate for a development environment
in config/environments/development.rb:
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
In production, :host should be set to the actual host of your application.
* Required for all applications. *
2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:
root to: "home#index"
* Not required for API-only Applications *
3. Ensure you have flash messages in app/views/layouts/application.html.erb.
For example:
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
* Not required for API-only Applications *
4. You can copy Devise views (for customization) to your app by running:
rails g devise:views
* Not required *
===============================================================================
開発環境用のメール送信の設定を行う
config/environments/development.rb に以下を追記します。
どこでも良いですが私はこの辺に追記します。
...(前略)
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
# ----- ここを追記 -----
# Devise mailer setting
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.delivery_method = :letter_opener_web
# ----- ここまで -----
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
...(後略)
root_url となる View を作成する
今回は home にしましょう。
bundle exec rails g controller Home index show
Running via Spring preloader in process 10675
create app/controllers/home_controller.rb
route get 'home/index'
get 'home/show'
invoke erb
create app/views/home
create app/views/home/index.html.erb
create app/views/home/show.html.erb
invoke helper
create app/helpers/home_helper.rb
invoke assets
invoke css
create app/assets/stylesheets/home.css
Rails.application.routes.draw do
get 'home/index'
get 'home/show'
root to: "home#index"
## 開発環境用letter_opener
mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
app/views/layouts/application.html.erb にメッセージ追加
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all' %>
</head>
<body>
<header style="margin-top:30px;">
<nav>
<!-- user_signed_in? はユーザがログインしているか調べる devise の Helper メソッド -->
<% if user_signed_in? %>
<!-- current_user は現在ログインしているUserオブジェクトを返す devise の Helper メソッド -->
<!-- *_path はUserモデルを作成したときに、deviseにより自動で作成されてますので、rake routes で確認できます -->
Logged in as <strong><%= current_user.email %></strong>.
<%= link_to 'プロフィール変更', edit_user_registration_path %> |
<%= link_to "ログアウト", destroy_user_session_path %>
<% else %>
<%= link_to "サインアップ", new_user_registration_path %> |
<%= link_to "ログイン", new_user_session_path %>
<% end %>
</nav>
</header>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= yield %>
</body>
</html>
config/initializers/devise.rb を少し編集しておきます
# The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = :get # ここを :delete から :get に編集
認証認可用の User モデルを作成
また appコンテナ の
ターミナルに戻って作業を進めます。
bundle exec rails g devise User
Running via Spring preloader in process 10707
invoke active_record
create db/migrate/20201226101859_devise_create_users.rb
create app/models/user.rb
insert app/models/user.rb
route devise_for :users
生成された migration ファイルのコメントを外して全部入りモリモリでいきましょう。
(migration ファイルのファイル名は各々変わると思うので rails g devise User
した時の出力などを見てみてください)
# frozen_string_literal: true
class DeviseCreateUsers < ActiveRecord::Migration[6.1]
def change
create_table :users do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
t.string :unlock_token # Only if unlock strategy is :email or :both
t.datetime :locked_at
t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
add_index :users, :confirmation_token, unique: true
add_index :users, :unlock_token, unique: true
end
end
app/models/user.rb も編集しておきます。
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:trackable, :confirmable, :lockable, :timeoutable
end
編集し終わったらまた appコンテナ のターミナルに戻って migration を実行しましょう。
bundle exec rails db:migrate
終わったら Rails サーバーを起動して動作確認します。
bundle exec rails s -b "0.0.0.0"
http://localhost:3000/
にアクセスして確認。
「サインアップ」をクリックして必要情報を入れ、「Sign up]ボタンを押す
http://localhost:3000/letter_opener
にアクセスすると認証用メールが確認できるので
「Confirm my account」のリンクを実行すると confirm が実行される
↓
「ログイン」からログインしてみる
「ログアウト」からログアウトできます。
良い感じですね! 簡単!
devise で表示する view を日本語化する
また appコンテナ の ターミナルに戻って作業を進めます。
bundle exec rails g devise:views:locale ja
config/application.rb を編集します。
require_relative "boot"
require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_mailbox/engine"
require "action_text/engine"
require "action_view/railtie"
require "action_cable/engine"
# require "sprockets/railtie"
# require "rails/test_unit/railtie"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module App
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 6.1
# ----- ここを追記 -----
# Devise i18n japanese
config.i18n.default_locale = :ja
# ----- ここまで -----
# Configuration for the application, engines, and railties goes here.
#
# These settings can be overridden in specific environments using the files
# in config/environments, which are processed later.
#
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("extras")
# Don't generate system test files.
config.generators.system_tests = nil
end
end
終わったら Rails サーバーを起動して動作確認します。
bundle exec rails s -b "0.0.0.0"
http://localhost:3000/
にアクセスして確認。「サインアップ」をクリックすると
日本語化できてますね!オッケー!!
今回はここまでです。おつかれさまでした!
今回のリポジトリはこちらです。
参考
- heartcombo / devise | GitHub
- 【Rails】deviseの使い方をマスターしてログイン認証機能を実装 | Pikawaka
- Deviseの設定手順をまとめてみた。 その1 導入編 | Qiita
- deviseを日本語表記にする。 | Qiita
- gem devise の module 翻訳 | 北山淳也| zenn
- Ruby on Railsを使って新規アプリを作成し、TOPページを表示させる | Qiita
Discussion
deviseインストールの際の
bundle install
rails g devise:install
bundle exec rails g devise:install
のrails g devise:installの部分は不要っぽいです!
/vendorにRailsをインストールしない際は、bundle exec不要だと最初で明言しているので、わかりづらくなってしまうかなと思いました
それとHomeコントローラー作成の際にはbundle execが抜けてしまっているので、細かい部分ですが指摘させていただきます
@takumin0423 さん
ご指摘ありがとうございます!修正しました 👍