ゴール
現在(2017/05/23)最新のRails5.1.0をベースにログイン認証付きの雛形アプリを以下の条件で作成する。
- いい感じの見た目(Bootstrap3ベース)にする。
- 日本語化する。
- Javascriptの管理にはRails5.1.0から導入されたYarnを用いる。
- Webpackは利用しない。
環境
以下の環境が構築済みであること。
※カッコ内は取得元。それ以外はgithub。
DB
mysql: 5.6.16 (brew)
Ruby
本体/パッケージ群管理
rbenv: 1.0.0
ruby-build: 20170322
rbenv-gemsets: 0.5.8
本体
ruby: 2.4.1 (rbenv)
パッケージ管理
bundler: 1.15.0 (gem)
Node
本体管理
nvm: 0.13.0
本体
node: 7.10.0 (nvm)
パッケージ管理
yarn: 0.24.5 (brew)
Rails
rails: 5.1.0 (gem)
前提
- WORK_DIR: Railsプロジェクトを構築するディレクトリ
- 事前に以下のインストールは終えていること
- mysql
- rbenv,ruby-build,rbenv-gemsets,ruby
- nvm,node,yarn
手順
Railsインストール
プロジェクトディレクトリ作成
% pwd
WORK_DIR
% mkdir sample_project
% cd sample_project; pwd
/WORK_DIR/sample_project
rbenvによるパッケージインストール
パッケージインストールの環境を設定する。
% echo 2.4.1 > .ruby-version
% echo sample > .rbenv-gemsets
% head .r*
==> .rbenv-gemsets <==
sample
==> .ruby-version <==
2.4.1
% rbenv versions
system
* 2.4.1 (set by /WORK_DIR/sample_project/.ruby-version)
% rbenv gemset active
sample global
Rubyインストール時のデフォルトのgemのみであることを確認する。
% gem list
*** LOCAL GEMS ***
bigdecimal (default: 1.3.0)
did_you_mean (1.1.0)
io-console (default: 0.4.6)
json (default: 2.0.2)
minitest (5.10.1)
net-telnet (0.1.1)
openssl (default: 2.0.3)
power_assert (0.4.1)
psych (default: 2.2.2)
rake (12.0.0)
rdoc (default: 5.0.0)
test-unit (3.2.3)
xmlrpc (0.2.1)
bundlerはgemコマンドにてインストールする。(以降のgemのインストールはbundleコマンドを利用する。)
% gem install bundler
Fetching: bundler-1.15.0.gem (100%)
Successfully installed bundler-1.15.0
Parsing documentation for bundler-1.15.0
Installing ri documentation for bundler-1.15.0
Done installing documentation for bundler after 5 seconds
1 gem installed
bundlerの追加を確認する。
% gem list | grep bundler
bundler (1.15.0)
Gmefileの雛形を生成し、インストールしたいバージョンのRails(5.1.0)を指定する。
% bundle init
Writing new Gemfile to /WORK_DIR/sample_project/Gemfile
% vim Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
gem "rails", "5.1.0"
Railsをインストール。
% bundle install
% rails -v
Rails 5.1.0
カレントディレクトリをRailsのホームディレクトリとしてプロジェクトを作成する。
本番環境でも利用できるようにDBはmysqlとする。
yarnを利用する場合は「--yarn」で明示的に指定可能だが、デフォルトで有効になっている為無くてもよい。
(rails new後にカレントディレクトリにnode_modulesディレクトリとpackage.jsonがあれば有効になっている)
% rails new . -d mysql
exist
create README.md
create Rakefile
create config.ru
create .gitignore
conflict Gemfile
Overwrite /WORK_DIR/sample_project/Gemfile? (enter "h" for help) [Ynaqdh] ★Enter入力
…
Bundle complete! 16 Gemfile dependencies, 70 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
run bundle exec spring binstub --all
* bin/rake: spring inserted
* bin/rails: spring inserted
Railsのデフォルトのパッケージ群をカスタマイズする。
- デバッグ用のパッケージ
- ログイン認証用のパッケージ
- asset関連のパッケージ(yarnを使わない場合のみ)
% vim Gemfile
※末尾に以下を追加
################################################################################
# Added
################################################################################
# for debug.
gem 'pry'
gem 'pry-doc'
gem 'pry-byebug'
gem 'pry-stack_explorer'
gem 'pry-rails'
# for devise.
gem 'devise'
gem 'devise-bootstrap-views'
gem 'devise-i18n'
gem 'devise-i18n-views'
# yarnを使わない場合は以下を追加
# gem 'jquery-rails'
# gem 'bootstrap-sass'
# gem "font-awesome-rails"
gem群インストール。
% bundle install
% bundle list
※付録参照
npm群インストール。
% yarn add jquery bootstrap-sass font-awesome
yarn add v0.24.5
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 📃 Building fresh packages...
success Saved lockfile.
success Saved 3 new dependencies.
├─ bootstrap-sass@3.3.7
├─ font-awesome@4.7.0
└─ jquery@3.2.1
✨ Done in 0.75s.
% yarn list
※付録参照
% head -100 package.json yarn.lock
※付録参照
DBの接続設定と接続確認
% vim config/database.yml
username/passwordを適切に設定
% mysql --version
mysql Ver 14.14 Distrib 5.6.16, for osx10.9 (x86_64) using EditLine wrapper
% mysql.server start
Starting MySQL
SUCCESS!
% rails db:create
Created database 'sample_project_development'
Created database 'sample_project_test'
% rails db
mysql> show databases;
以下のDBが作成されていること
sample_project_development
sample_project_test
mysql> quit
Bye
%
ログイン認証(Devise)環境構築
Deviseインストール
応答がない場合はspring stop
orpkill spring
でspringを停止後再度実行。
% rails g devise:install
Running via Spring preloader in process 34661
create config/initializers/devise.rb
create config/locales/devise.en.yml
===============================================================================
Some setup you must do manually if you haven't yet:
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.
2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:
root to: "home#index"
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>
4. You can copy Devise views (for customization) to your app by running:
rails g devise:views
===============================================================================
メール関連の設定追加。
下記は例としてgmailを利用。
xxxx/yyyyは地震で取得したアカウントを利用する。
Please log in via your web browser…のエラーが発生する場合は、gmailのセキュリティレベルを下げる。
http://www.atmarkit.co.jp/ait/articles/1409/03/news109.html
% vim config/environments/development.rb
29 # Don't care if the mailer can't send.
30 config.action_mailer.raise_delivery_errors = true ★変更:false->true
31
32 config.action_mailer.perform_caching = false
33
34 config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } ★追加
35
36 config.action_mailer.smtp_settings = { ★追加
37 :address => 'smtp.gmail.com',
38 :port => 587,
39 :domain => 'example.com',
40 :user_name => 'xxxx@gmail.com',
41 :password => 'yyyy',
42 :authentication => :plain,
43 :enable_starttls_auto => true
44 }
ログイン対象のモデル作成
認証に利用するモデルを作成する。
モデル名はUserとしたが任意のモデル名を指定できる。(複数のモデルを定義することも可能)
% rails g devise user
Running via Spring preloader in process 53666
invoke active_record
create db/migrate/20170522085148_devise_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
insert app/models/user.rb
route devise_for :users
% rails db:migrate
== 20170524033356 DeviseCreateUsers: migrating ================================
-- create_table(:users)
-> 0.0096s
-- add_index(:users, :email, {:unique=>true})
-> 0.0290s
-- add_index(:users, :reset_password_token, {:unique=>true})
-> 0.0182s
== 20170524033356 DeviseCreateUsers: migrated (0.0571s) =======================
Devise関連ページの作成(サインイン、アカウント管理など)
% rails g devise:views:bootstrap_templates
Running via Spring preloader in process 61262
create app/views/devise
create app/views/devise/confirmations/new.html.erb
create app/views/devise/mailer/confirmation_instructions.html.erb
create app/views/devise/mailer/reset_password_instructions.html.erb
create app/views/devise/mailer/unlock_instructions.html.erb
create app/views/devise/passwords/edit.html.erb
create app/views/devise/passwords/new.html.erb
create app/views/devise/registrations/edit.html.erb
create app/views/devise/registrations/new.html.erb
create app/views/devise/sessions/new.html.erb
create app/views/devise/shared/_links.html.erb
create app/views/devise/unlocks/new.html.erb
この時点でログイン画面の確認可能(スタイル未適用)
% rails s
http://localhost:3000でRailsデフォルトのwelcomeページ表示
http://localhost:3000/users/sign_up にアクセスしユーザ作成(作成後自動的にwelcomページに遷移)
ホーム画面用意(ログイン後に表示する画面)
ルーティング設定
% vim config/routes.rb
Rails.application.routes.draw do
devise_for :users
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root to: 'home#index'
end
% rails routes
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
user_password PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
POST /users/password(.:format) devise/passwords#create
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
user_registration PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
POST /users(.:format) devise/registrations#create
root GET / home#index
コントローラ設定
% rails g controller home
Running via Spring preloader in process 66110
create app/controllers/home_controller.rb
invoke erb
create app/views/home
invoke test_unit
create test/controllers/home_controller_test.rb
invoke helper
create app/helpers/home_helper.rb
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/home.coffee
invoke scss
create app/assets/stylesheets/home.scss
indexアクション追加
% vim app/controllers/home_controller.rb
class HomeController < ApplicationController
def index
end
end
indexビュー追加
% vim app/views/home/index.html.erb
<h1>HOME</h1>
Welcome sample project!
Home画面確認
http://localhost:3000/ (Homeページ表示)
bootstrap関連の設定
ロードするStylesheetの設定
yarnでインストールしたものはnode_modules以下のディレクトリから指定する。
ナビゲーションバー追加による調整用スタイル( node_modules/bootstrap-sass/assets/stylesheets/bootstrap/_custom.scss
)は個別に読み込ませる。 (この時点では存在しない。後の手順で作成。)
% mv app/assets/stylesheets/application.{css,scss}
% vim app/assets/stylesheets/application.scss
※SASSの形式で登録(bootstrap-sass/font-awesomeはパスを指定する必要あり)
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
* vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require_tree .
*= require_self
*/
@import 'bootstrap-sass/assets/stylesheets/bootstrap';
@import 'bootstrap-sass/assets/stylesheets/bootstrap/custom';
@import "font-awesome/scss/font-awesome";
@import "devise_bootstrap_views";
ロードするJavascriptの設定
yarnでインストールしたものはnode_modules以下のディレクトリから指定する。
% vim app/assets/javascripts/application.js
※jquery/bootstrapを追加
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
// vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require rails-ujs
//= require turbolinks
//= require jquery/dist/jquery ※jqueryのみでもロードできるがrailsの仕様を要確認
//= require bootstrap-sass/assets/javascripts/bootstrap ※こちらはパスを指定しないとロードできない
//= require_tree .
font-awesomeのパス変更
node_modules/font-awesome/scss/font-awesome.scssのStylesheetを起点にパスが設定されているが、
font-awesome.scssはassets/font-awesome.cssとして提供されるため、デフォルトの相対パスでは参照できない。
よって参照できる相対パスに変更する。
% grep '^$fa-font-path' node_modules/font-awesome/scss/_variables.scss
$fa-font-path: "../fonts" !default;
% vim node_modules/font-awesome/scss/_variables.scss
% grep '^$fa-font-path' node_modules/font-awesome/scss/_variables.scss
$fa-font-path: "font-awesome/fonts" !default;
なおRails.application.config.assets.paths
にパスを追加しつじつまを合わせることも考えたが、階層を一段登る表現(../fonts
)により実現できなかった。
font-awesomeを例にすると、 以下のように解釈されてしまう。
node_modules/font-awesome/fonts/fontawesome-webfont.woff2 -> http://localhost:3000/fonts/fontawesome-webfont.woff2
理由は、font-awesome.scss(がimportする_variables.scss含む)はアセットパイプラインにより統合され以下のようにassets配下にフラットに展開される為である。
node_modules/font-awesome/scss/font-awesome.scss -> http://localhost:3000/assets/application.css (アセットパイプラインにより統合されたcss)
よって前述のように相対パスを変更すれば、以下のように解釈される。
node_modules/font-awesome/fonts/fontawesome-webfont.woff2 -> http://localhost:3000/assets/font-awesome/fonts/fontawesome-webfont.woff2
スタイルの調整
ナビゲーションバーを追加することによってbodyタグのスタイルの調整が必要になる。
以下のテーマのtheme.cssを参考に調整用のスタイルを設定する。
% vim node_modules/bootstrap-sass/assets/stylesheets/bootstrap/_custom.scss
以下を追加
body {
padding-top: 70px;
}
見た目の調整を行うときはこちらをカスタマイズしていく。
ナビゲーションバーの作成
ログインユーザ情報の表示、ログアウトリンクの表示の為にナビゲーションバーを用意。
ユーザ情報はログインした場合のみ表示するようにuser_signed_in?
によりログイン状態をチェック。
% vim app/views/layouts/application.html.erb
bodyタグ内部を以下に置き換え
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#"><%= Rails.application.class.to_s.split('::').first %></a>
</div>
<div id="navbar" class="navbar-collapse collapse" aria-expanded="false" style="height: 1px;">
<ul class="nav navbar-nav navbar-right">
<% if user_signed_in? %>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<%= current_user.email %> <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="#">設定メニュー1</a></li>
<li><a href="#">設定メニュー2</a></li>
<li role="separator" class="divider"></li>
<li>
<a data-method="delete" href="/users/sign_out" rel="nofollow" data-toggle="tooltip" data-placement="bottom">
<i class="fa fa-sign-out" aria-hidden="true"></i>ログアウト
</a>
</li>
</ul>
</li>
<% end %>
</ul>
</div><!--/.navbar-collapse -->
</div>
</nav>
<!-- Navigation bar -->
<div class="container">
<!-- Notice -->
<% if notice.present? %>
<div class="alert alert-dismissable alert-success">
<button type="button" class="close" data-dismiss="alert">×</button <p><%= notice %></p>
</div>
<% end %>
<% if alert.present? %>
<div class="alert alert-dismissable alert-danger">
<button type="button" class="close" data-dismiss="alert">×</button <p><%= alert %></p>
</div>
<% end %>
<%= yield %>
</div>
</body>
スタイルの適用確認
以下のページがBootstrap化されていることを確認。
(手順通りに進めるとHome画面が表示されている為、右上のドロップダウンメニューから一旦ログアウトが必要)
http://localhost:3000/ (この時点では閲覧制限を設定していないのでHome画面が表示される)
http://localhost:3000/users/sign_in
http://localhost:3000/users/sign_up
http://localhost:3000/users/password/new
閲覧制限
設定
サインイン、サインアップ、パスワード再通知画面以外の全てのページにおいてログインが必要になるように設定。
% vim app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user! ★追加
end
Home画面確認
http://localhost:3000/ にログアウトした状態でアクセス(エラーメッセージとともに/users/sign_inページ表示)
※エラーメッセージ: You need to sign in or sign up before continuing.
Devise関連画面の日本語化
辞書ファイル設置
% rails g devise:views:locale ja
Running via Spring preloader in process 58302
create config/locales/devise.views.ja.yml
ロケールの設定変更
% vim config/application.rb
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module SampleProject
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.1
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
config.i18n.default_locale = :ja ★追加
end
end
日本語化適用確認
以下のページが日本語化されていることを確認
http://localhost:3000/users/sign_in
http://localhost:3000/users/sign_up
http://localhost:3000/users/password/new
付録
gem一覧
% bundle list
Gems included by the bundle:
* actioncable (5.1.0)
* actionmailer (5.1.0)
* actionpack (5.1.0)
* actionview (5.1.0)
* activejob (5.1.0)
* activemodel (5.1.0)
* activerecord (5.1.0)
* activesupport (5.1.0)
* addressable (2.5.1)
* arel (8.0.0)
* bcrypt (3.1.11)
* bindex (0.5.0)
* binding_of_caller (0.7.2)
* builder (3.2.3)
* bundler (1.15.0)
* byebug (9.0.6)
* capybara (2.13.0)
* childprocess (0.7.0)
* coderay (1.1.1)
* coffee-rails (4.2.1)
* coffee-script (2.4.1)
* coffee-script-source (1.12.2)
* concurrent-ruby (1.0.5)
* debug_inspector (0.0.3)
* devise (4.3.0)
* devise-bootstrap-views (0.0.11)
* devise-i18n (1.1.2)
* devise-i18n-views (0.3.7)
* erubi (1.6.0)
* execjs (2.7.0)
* ffi (1.9.18)
* globalid (0.4.0)
* i18n (0.8.1)
* jbuilder (2.6.4)
* listen (3.1.5)
* loofah (2.0.3)
* mail (2.6.5)
* method_source (0.8.2)
* mime-types (3.1)
* mime-types-data (3.2016.0521)
* mini_portile2 (2.1.0)
* minitest (5.10.2)
* multi_json (1.12.1)
* mysql2 (0.4.6)
* nio4r (2.0.0)
* nokogiri (1.7.2)
* orm_adapter (0.5.0)
* pry (0.10.4)
* pry-byebug (3.4.2)
* pry-doc (0.10.0)
* pry-rails (0.3.6)
* pry-stack_explorer (0.4.9.2)
* public_suffix (2.0.5)
* puma (3.8.2)
* rack (2.0.3)
* rack-test (0.6.3)
* rails (5.1.0)
* rails-dom-testing (2.0.3)
* rails-html-sanitizer (1.0.3)
* railties (5.1.0)
* rake (12.0.0)
* rb-fsevent (0.9.8)
* rb-inotify (0.9.8)
* responders (2.4.0)
* ruby_dep (1.5.0)
* rubyzip (1.2.1)
* sass (3.4.24)
* sass-rails (5.0.6)
* selenium-webdriver (3.4.0)
* slop (3.6.0)
* spring (2.0.2)
* spring-watcher-listen (2.0.1)
* sprockets (3.7.1)
* sprockets-rails (3.2.0)
* thor (0.19.4)
* thread_safe (0.3.6)
* tilt (2.0.7)
* turbolinks (5.0.1)
* turbolinks-source (5.0.3)
* tzinfo (1.2.3)
* uglifier (3.2.0)
* warden (1.2.7)
* web-console (3.5.1)
* websocket (1.2.4)
* websocket-driver (0.6.5)
* websocket-extensions (0.1.2)
* xpath (2.0.0)
* yard (0.9.9)
npm一覧
% yarn list
yarn list v0.24.5
├─ bootstrap-sass@3.3.7
├─ font-awesome@4.7.0
└─ jquery@3.2.1
✨ Done in 0.13s.
yarn add により設定ファイルも更新される。
% head -100 package.json yarn.lock
==> package.json <==
{
"name": "sample_project",
"private": true,
"dependencies": {
"bootstrap-sass": "^3.3.7",
"font-awesome": "^4.7.0",
"jquery": "^3.2.1"
}
}
==> yarn.lock <==
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
bootstrap-sass@^3.3.7:
version "3.3.7"
resolved "https://registry.yarnpkg.com/bootstrap-sass/-/bootstrap-sass-3.3.7.tgz#6596c7ab40f6637393323ab0bc80d064fc630498"
font-awesome@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133"
jquery@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.2.1.tgz#5c4d9de652af6cd0a770154a631bba12b015c787"
jQueryバージョン確認
yarnによりインストールしたjqueryが読み込まれているかはブラウザの開発ツールのコンソールに$().jquery
を打ち込んでバージョンを確認。
参照
http://sssslide.com/speakerdeck.com/yyagi/here-comes-a-rails-5-dot-1
https://sheerdevelopment.com/posts/using-yarn-with-rails
http://pixelatedworks.com/articles/embracing-change-rails51-adopts-yarn-webpack-and-the-js-ecosystem/
http://qiita.com/kikunantoka/items/ab9d612abc213c734183
http://qiita.com/skuroki@github/items/f3b6dd12f4ff9e0a23d1
http://qiita.com/ryohashimoto/items/a8ba7bb8d6f340894188