8/11の学習日記
概要
- レイアウト/デザイン共通化
- エラー処理
部分テンプレート
app/views/layouts/application.html.erb
<body>
<div id="wrapper">
<%= render "shared/header" %>
<div id="container">
<%= yield %>
</div>
<%= render "shared/footer" %>
</div>
</body>
app/views/shared/_header.html.erb
<header>
<span class="logo-mark">Baukis</span>
</header>
<header>
<span class="logo-mark">Baukis</span>
</header>
app/views/shared/_footer.html.erb
<footer>
<p>© 2020 Ono</p>
</footer>
<footer>
<p>© 2020 Ono</p>
</footer>
ヘルパーメソッド
app\helpers\application_helper.rb
module ApplicationHelper
def document_title
if @title.present?
"#{@title} - Baukis"
else
"Baukis"
end
end
end
Sass/SCSS
アセットパイプライン
Sass/SCSS
スタイルシートの切り替え
app\assets\stylesheets\staff.css
/*
*= require_tree ./staff
*/
Rails.application.config.assets.version = "1.0"
Rails.application.config.assets.paths << Rails.root.join("node_modules")
Rails.application.config.assets.precompile += %w( staff.css )
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
div#wrapper {
position: relative;
box-sizing: border-box;
min-height: 100%;
margin: 0 auto;
padding-bottom: 48px;
background-color: #cccccc;
}
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
div#wrapper {
position: relative;
box-sizing: border-box;
min-height: 100%;
margin: 0 auto;
padding-bottom: 48px;
background-color: #cccccc;
}
staff.html.erb
<head>
<title>Baukis</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "staff", media: "all", "data-turbolinks-track": "reload" %>
<%= javascript_pack_tag "application", "data-turbolinks-track": "reload" %>
</head>
application_controller.rb
class ApplicationController < ActionController::Base
layout :set_layout
private def set_layout
if params[:controller].match(%r{\A(staff|admin|customer)})
Regexp.last_match[1]
else
"customer"
end
end
ヘッダとフッタのスタイル
header {
padding: 5px;
background-color: #448888;
color: #eeeeee;
span.logo-mark {
font-weight: bold;
}
}
footer {
bottom: 0;
position: absolute;
width: 100%;
background-color: #666666;
color: #eeeeee;
p: {
texr-align: center;
padding: 5px;
margin: 0;
}
}
見出しのスタイル
div#wrapper {
div#container {
h1 {
font-weight: normal;
font-size: 16px;
color: #eeeeee;
margin: 0;
padding: 9px 6px;
background-color: #cccccc;
}
}
}
色を変数で表現する
$dark_gray: #666666;
$gray: #cccccc;
$light_gray: #eeeeee;
$very_light_gray: #fafafa;
$dark_cyan: #448888;
$very_dark_cyan: darke($dark_cyan, 25%);
a
@import "colors";
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
div#wrapper {
position: relative;
box-sizing: border-box;
min-height: 100%;
margin: 0 auto;
padding-bottom: 48px;
background-color: $gray;
}
header {
padding: 5px;
background-color: $dark_cyan;
color: $very_light_gray;
span.logo-mark {
font-weight: bold;
}
}
footer {
bottom: 0;
position: absolute;
width: 100%;
background-color: $dark_cyan;
color: $very_light_gray;
p {
text-align: center;
padding: 5px;
margin: 0;
}
}
寸法を変数で表現する
アセットのプリコンパイル
productionモードのデータベース作成
$bin/rails db:create RAILS_ENV=production
assets:precompileタスク実行
$bin/rails assets:precompile
暗号化された資格情報
- credential.yml.enc
- master.key
$EDITOR=vim bin/rails credential:edit
productionモードで起動
$export RAILS_SERVE_STATIC_FILES=1
$bin/rails s -e production -b 0.0.0.0
エラーページ
例外処理の基礎知識
例外とは
raisメソッドと例外処理構文
raise ArgumentError, "the first argment must be a string"
begin
resucue => e1
resucue => e2
ensure
end
クラスメソッドrescue_from
resque_from Forbidden, with: :rescue403
private def resque403(e)
@exception = e
render template: "errors/forbidden", status: 403
end
500 Internal Server Error
準備作業
# Code is not reloaded between requests.
# config.cache_classes = true
config.cache_classes = false
a
class Staff::TopController < ApplicationController
def index
raise
render action: "index"
end
end
$tail -f apps/baukis/log/production.log
例外の補足
class ApplicationController < ActionController::Base
layout :set_layout
rescue_from StandardError, with: :rescue500
private def set_layout
if params[:controller].match(%r{\A(staff|admin|customer)})
Regexp.last_match[1]
else
"customer"
end
end
private def rescue500(e)
render "error/internal_server_error", status: 500
end
ビジュアルデザイン
/*
*= require_tree ./shared
*= require_tree ./staff
*/
403 Forbidden
例外の補足
class ApplicationController < ActionController::Base
layout :set_layout
class Forbidden < ActionController::ActionControllerError; end
class IpAddressRejected < ActionController::ActionControllerError; end
rescue_from StandardError, with: :rescue500
rescue_from Forbidden, with: :rescue403
rescue_from IpAddressRejected, with: :rescue403
private def set_layout
if params[:controller].match(%r{\A(staff|admin|customer)})
Regexp.last_match[1]
else
"customer"
end
end
private def rescue403(e)
render "error/forbidden", status: 403
end
private def rescue500(e)
render "error/internal_server_error", status: 500
end
ERBテンプレートの作成
<div id="error">
<h1>403 Forbidden</h1>
<p>
<%
case @exception
when ApplicationController::IpAddressRejected
"あなたのIpアドレス(#{request.ip})は利用できません"
else
"指定ページの閲覧権限がありません"
%>
</p>
</div>
動作確認
404 Not Found
Rails.application.routes.configure do
config.exceptions_app = ->(env) do
request = ActionDispatch::Request.new(env)
action =
case request.path.info
when "/404"; :not_found
when "/422"; :unprocessable_entity
else; :internal_server_error
end
ErrorsController.action(action).call(env)
end
end
bin/rails g controller errors
例外ActionController::RoutingErrorの処理
例外ActiveRecord::RecordNotFoundの処理
エラー処理モジュールの抽出
抽出対象のコード
ErrorHandlersモジュールの作成
module ErrorHandler
extend ActiveSupport::Concern
included do
rescue_from StandardError, with: :rescue500
rescue_from ApplicationController::Forbidden, with: :rescue403
rescue_from ApplicationController::IpAddressRejected, with: :rescue403
rescue_from ActiveRecord::RecordNotFound, with: :rescue404
end
private def rescue403(e)
render "error/forbidden", status: 403
end
private def rescue404(e)
render "errors/not_found", status: 404
end
private def rescue500(e)
render "error/internal_server_error", status: 500
end
end
ApplicationControllerの書き換え
class ApplicationController < ActionController::Base
layout :set_layout
class Forbidden < ActionController::ActionControllerError; end
class IpAddressRejected < ActionController::ActionControllerError; end
include ErrorHandlers
private def set_layout
if params[:controller].match(%r{\A(staff|admin|customer)})
Regexp.last_match[1]
else
"customer"
end
end
end