自作のサービスを作る際、環境構築同様毎度同じことをやるのでまとめておく。
事前準備
rails s
でページ表示済み
Deviseインストールする。
Gemfileに追加する
gem "devise"
bundle install
bin/rails g devise:install
↑このコマンドを実行すると4つのセットアップ方法が表示されるので従う。
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
本番用もこの時点で記述しておく
# 本番環境ではhost名を指定
config.action_mailer.default_url_options = { host: 'xxxx.com' }
ルーティングの設定を行う
root to: "home#index"
次にトップページ用のコントローラーを生成
今回はDeivseの指定に合わせてhome
index
で用意。対応させていれば自由に変更OK
bin/rails g controller home index
2行のflashメッセージを追加する。
自分はbootstrapのcontainerクラス内かつ、パーシャル化させる。
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
Deviseのビューファイルをコピー
bin/rails g devise:views
Userモデルを作成
bin/rails g devise User
usersテーブルを作成
bin/rails db:migrate
↑要らぬ情報だけど、この時なぜか(この記事内では関係なかったため割愛)usersテーブルが既にありますというエラーが出たためrails db:migrate:reset
で対処した。
この時点で、ログインしないとアクセスできないようにする。
もしこれをしない場合は、rails s
で確認する際に/users/sign_in
で確認することを忘れないよう注意。
作りたいサービスによるが、ログインしていなくてもトップページ一覧は閲覧できるようにしたい場合は、application_controller.rb
ではなく、トップページ(今回はhome)のControllerに記載+index
のみ除外などの工夫をすべき?
class ApplicationController < ActionController::Base
before_action :authenticate_user!
end
フォームが正しく表示されているか確認
bin/rails s
↑要らぬ情報2だけど、自分はDocker使用していて、一旦down
して再度up
しないとルーティングエラーになった。要は色々生成しているから更新しようということ。
これでお馴染みのフォームが生成されていればOK
DeviseにBootstrapを適用
必要なものをインストール(バージョンは指定しなくても。)
$ yarn add bootstrap@4.4.1 jquery@3.5.1 popper.js@1.16.1
config/webpack/environment.jsに追記
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.append('Provide', new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Popper: ['popper.js', 'default']
}))
module.exports = environment
app/javascript/packs/application.jsに追記
require("bootstrap/dist/js/bootstrap")
application.cssの拡張子cssをscssに変更
最後にapp/assets/stylesheets/application.scssに追記
/*
*= require_tree .
*= require_self
*/
@import "bootstrap/scss/bootstrap";
Viewを編集
レスポンシブ対応のviewport
を忘れずに記載しておく
..
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<meta name="viewport" content="width=device-width,initial-scale=1">
..
<body>
<header>
<nav class="navbar navbar-expand navbar-light">
<%= link_to "サンプル", root_path, class: 'navbar-brand' %>
<div id="Navber">
<ul class="navbar-nav">
<% if user_signed_in? %>
<li class="nav-item active">
<%= link_to 'アカウント編集', edit_user_registration_path, class: 'nav-link' %>
</li>
<li class="nav-item active">
<%= link_to 'ログアウト', destroy_user_session_path, method: :delete, class: 'nav-link' %>
</li>
<% else %>
<li class="nav-item active">
<%= link_to "新規登録", new_user_registration_path, class: 'nav-link' %>
</li>
<li class="nav-item active">
<%= link_to "ログイン", new_user_session_path, class: 'nav-link' %>
</li>
<% end %>
</ul>
</div>
</nav>
</header>
<div class="container">
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
..
devise用のbootstrapのGemを追加する
(後の日本語化のGemもこの時点で追加しておきます。)
..
# 日本語化
gem 'rails-i18n', '~> 6.0'
gem 'devise-i18n'
# Bootstrap
gem 'devise-bootstrap-views', '~> 1.0'
既にdeviseのviewsをinstallしている場合は、下記コマンドでbootstrap用のテンプレートに変更する
(このコマンドを使用すると、devise関連のviewにbootstrap用のclassが追加される)
(このコマンドをしないと、ページはbootstrap適用されるが、devise関連が適用されない)
**このコマンドを打つと、既にあるviewファイルとコンフリクトを起こすがa (all, overwrite this and all others)
で上書きすれば大丈夫
bin/rails g devise:views:bootstrap_templates
http://localhost:3000 で確認してみましょう
このようになっていれば無事適用
Deviseに名前も登録する
まず、usersテーブルにname
を追加する。
email
に適用されているユニークインデックスをnameに適用
rails g migration add_name_to_users name:string:uniq
class AddNameToUsers < ActiveRecord::Migration[6.0]
def change
add_column :users, :name, :string
add_index :users, :name, unique: true
end
end
bin/rails db:migrate
name
にバリデーション設定
..
validates :username, uniqueness: true, presence: true
設定ファイルで認証キーを変更
- # config.authentication_keys = [:email]
+ config.authentication_keys = [:username]
viewファイルを変更
まずは新規登録画面
name
を一番上にする場合は、デフォルトではemail
に設定されているautofocus
を変更する
..
<%= bootstrap_devise_error_messages! %>
<!-- nameの入力欄を追加 -->
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, autofocus: true, autocomplete: 'name', class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email, autocomplete: 'email', class: 'form-control' %>
</div>
..
StrongParameterにname
追加
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
added_attrs = [ :name, :email, :password, :password_confirmation ]
devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
devise_parameter_sanitizer.permit :account_update, keys: added_attrs
devise_parameter_sanitizer.permit :sign_in, keys: added_attrs
end
end
ログインも変更
..
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, autofocus: true, autocomplete: 'name', class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email, autocomplete: 'email', class: 'form-control' %>
</div>
..
ここまでで、新規登録/ログインともに名前込みで出来るようになったと思います
deviseを日本語に
..
config.load_defaults 6.0
# 日本語
config.i18n.default_locale = :ja
# タイムゾーン変更
config.time_zone = 'Asia/Tokyo'
..
一度サーバーを落ちしてから確認してみてください。
http://localhost:3000
日本語の変更
下記のコマンドで生成されるdevise.views.ja.yml
内を編集することで変更出来る
bin/rails g devise:i18n:locale ja
- アカウント登録⇨新規登録
- パスワードを忘れましたか?⇨パスワードの再設定
の方が自然に感じると思います。