見出し画像

Ruby on Rails6習得編 Ruby on Rails 6 実践ガイド Chapter6 エラーページ


こちらの書籍について学んだことです。

Chapter6 エラーページ

6.1 例外処理の基礎知識

6.1.1 例外とは

exception
一般には変則的な事態のこと。

rubyには例外を表現するためのExceptionクラスが用意されている。

このクラスのインスタンスは、例外の発生元から例外処理のコードへ「変則的な事態」に関する情報を伝達するために利用される。

railsプログラマが普段目にする例外は、Exceptionクラスそのもののインスタンスではなく、Exceptionクラスの子孫クラスのインスタンス。
たとえば、データベーステーブルからレコードを取得する際に、ActiveRecord::RecordNotFoundという例外が発生することがある。

ActiveRecord::ActiveRecordError<-StandardError<-Exception
のようになっている。

本書で取り扱う例外はほとんどがStandardErrorの子孫
特記ない限りStandardErrorを基準にする。

6.1.2 raiseメソッドと例外処理構文

raiseメソッド

例外を発生させるにはraiseメソッドを使用する。
raiseメソッドの第1引数には例外のクラス名、第2引数(省略可)には例外を説明するメッセージを指定する。
次の例は、ArgumentError(引数が誤っていることを示す例外。StandardErrorを継承)を発生させる。

raise ArgumentError,"the first argument must be a string"

引数なしで単にraiseとすれば、StandardErrorを継承するRuntimeErrorが発生する。
引数に文字列を指定すれば、その文字列をメッセージとするRuntimeErrorが発生する。

例外処理の書き方

ruby言語の例外処理構文を模式的に示すと、次のようになる。

----------------------------------------
begin
 X
rescue E1 => e1
 Y1
rescue E2 => e2
 Y2
ensure
 Z
end
----------------------------------------

X,Y1,Y2,Zは任意のrubyコードで、複数行に渡っても大丈夫。
E1,E2はExceptionクラスの子孫。
Xで例外が発生すると、Xの処理は中断。
それがE1インスタンスならe1に変数セットしてY1が実行
それがE2インスタンスならe2に変数セットしてY2が実行
E1でもE2でもなければシステムエラー。
ZはXで例外が発生してもしなくても実行

begin,rescue,ensue,endはいずれもrubyの予約語

beginからendまでが例外処理が行われる範囲

rescue節には例外が発生したときの処理を記述する
rescue節は複数回書ける

ensure節には必ず実行すべき処理を記述する
ensure節は省略可能で、多くても1回しか書けない


6.1.3 クラスメソッド resque_form

rescure_formというクラスメソッドが用意されている。
アクション内で発生した例外の処理方法を簡単に指定できる。

rescure_form Active::RecordNotFound, with: :rescue403

これをApplicationControllerクラスの定義の中で記述すれば、任意のアクションにおいて例外ActiveRecord::RecordNotFoundが発生したときにアクションが中断されてrescure403に処理が移行する。

次に示すのはrescue403の実装例

----------------------------------------
private def rescue403(e)
 @exception = e
 render template: "errors/forbidden", status: 403
end
----------------------------------------

むず!

rescue_fromによって例外処理を委任されるメソッドはprivateメソッドとして定義する。
また引数として例外オブジェクトを受けるように実装する必要がある。

引数として渡ってきた例外オブジェクトをインスタンス変数@exceptionにセットして、
app/views/errors/forbidden.html.erbをERBテンプレートとしてHTML文書を生成
renderメソッドに与えているstatusオプションは、HTTPレスポンスのステータスコード

6.2 500 Internal Server Error

HTTPステータス500は、Webサーバーで何らかのエラーが発生したことを示す。
本来エラーは発生してはならないが、バグのないソフトウェアは存在しない。
あらかじめ異常事態の発生に備えておく。

6.2.1 準備作業

本章ではproductionモードにおけるアプリケーションの振る舞いをカスタマイズする。
通常、このモードではソースコードを変更してもアプリケーション自体を再起動しない限りアプリケーションんの振る舞いに反映されない。

それでは開発しにくいため、一時的に設定を変更する。

config/environments/production.rb修正後
----------------------------------------
:
config.cache_classes = false
:
----------------------------------------

そして、例外が発生するように、staff/top#indexアクションを書き換える

app.controllers/staff/top_controller.rb
----------------------------------------
class Staff::TopController < ApplicationController
 def index
   raise
   render action: "index"
 end
end
----------------------------------------

そして、productionモードでBaukis2を起動する。
bin/rails s -e production -b 0.0.0.0

そして下記にアクセス
http://example.com:3000/staff

すると、エラー画面になる。

画像1


このエラー画面をカスタマイズするのが、この節の目標。

コラム:productionモードのログを見るには

productionモードでrailsアプリケーションを起動した場合、ターミナルにログが表示されない。
しかし、logディレクトリのproduction.logというファイルにログが記録されている。
ホストOS側のターミナルで次のコマンドを実行すれば、ログを見ながら動作確認を行う事が可能。

tail -f apps/baukis2/log/production.log

いや、baukis2の中にいるなら下記のコマンドが正しいわ
tail -f log/production.log

tailはどんな意味?
→ファイルの最後数行を見るコマンド
https://eng-entrance.com/linux-command-tail

なるほどね

6.2.2 例外の捕捉

続いて、この例外を処理するコードを実装する

app/controllers/application_controller.rb
----------------------------------------
class ApplicationController < ActionController::Base
 #レイアウトをどのメソッドで決めるか
 layout :set_layout
 
 #StandardErrorがあったら、rescue500メソッドを呼び出す
 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
 
 #StandardErrorがあったときに表示されるページの設定
 private def rescue500(e)
   render "errors/internal_server_error", status: 500
 end
end
----------------------------------------

errors/internal_server_errorはまだないね!
これはapp/views/errors/internal_server_error.html.erbを表す。

ここまでだと、エラーページになって表示されない。
いったんこのまま進める。

6.2.3 ビジュアルデザイン

エラー画面のビジュアルデザインを整える。

ERBテンプレートを置くディレクトリを作成する。
今回はかっこよくコマンドでキメる
mkdir -p app/views/errors

できた!

かっこよくファイルを作成することできないかなぁ・・・

下記コマンドを試してみる
touch app/views/errors/internal_server_error.html.erb

できた!

app/views/errors/internal_server_error.html.erb新規作成
----------------------------------------
<div id="error">
 <h1>500 Internal Server Error</h1>
 <p>申し訳ございません。システムエラーが発生しました。</p>
</div>
----------------------------------------

次に、スタイルシートを作成する。
エラー画面用のスタイルシートはアプリケーション全体で共通化することにする。

今回もかっこよくコマンドでキメるぞー!
mkdir -p app/assets/stylesheets/shared
touch app/assets/stylesheets/shared/errors.scss

作成できた!

スタイルは下記のようにしていく
app/assets/stylesheets/shared/errors.scss
----------------------------------------
$dark_gray: #666666;
$very_light_gray: #fafafa;
div#error{
 width: 600px;
 margin: 20px auto;
 padding: 20px;
 border-radius: 10px;
 border: solid 4px $dark_gray;
 background-color: $very_light_gray;
 text-align: center;
 p.url{font-family: monospace;}
}
----------------------------------------

そして、アセットパイプラインの対象ディレクトリにsharedを加える

app/assets/stylesheets/staff.css
----------------------------------------
/*
*= require_tree ./shared
*= require_tree ./staff
*/
----------------------------------------
app/assets/stylesheets/admin.css
----------------------------------------
/*
*= require_tree ./shared
*= require_tree ./admin
*/
----------------------------------------
app/assets/stylesheets/customer.css
----------------------------------------
/*
*= require_tree ./shared
*= require_tree ./customer
*/
----------------------------------------

そしてアセットをプリコンパイル

bin/rails assets:precompile RAILS_ENV=production

前は末尾のやつついてなかったな・・・
本本環境用のアセットプリコンパイルなんだろうな!

ログ
----------------------------------------
bash-4.4$ bin/rails assets:precompile RAILS_ENV=production
yarn install v1.12.3
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.98s.
yarn install v1.12.3
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.2.11: The platform "linux" is incompatible with this module.
info "fsevents@1.2.11" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning " > webpack-dev-server@3.10.3" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "webpack-dev-server > webpack-dev-middleware@3.7.2" has unmet peer dependency "webpack@^4.0.0".
[4/4] Building fresh packages...
Done in 83.43s.
I, [2020-02-23T14:07:12.446333 #717]  INFO -- : Writing /apps/baukis2/public/assets/admin-6a389a316de850fa63407f6a6f065a17c4051e3d3a652ffe61817dc3b459d6ae.css
I, [2020-02-23T14:07:12.449253 #717]  INFO -- : Writing /apps/baukis2/public/assets/admin-6a389a316de850fa63407f6a6f065a17c4051e3d3a652ffe61817dc3b459d6ae.css.gz
I, [2020-02-23T14:07:12.452198 #717]  INFO -- : Writing /apps/baukis2/public/assets/customer-a4234a2bf630e8467b2e188d3e87ae6d12995ac013abc703d953f31fa953193e.css
I, [2020-02-23T14:07:12.455957 #717]  INFO -- : Writing /apps/baukis2/public/assets/customer-a4234a2bf630e8467b2e188d3e87ae6d12995ac013abc703d953f31fa953193e.css.gz
I, [2020-02-23T14:07:12.458748 #717]  INFO -- : Writing /apps/baukis2/public/assets/staff-11e27d3f6895cbb72541815d7588bf06f98221a2e8f42d1be3bdbe11275393ab.css
I, [2020-02-23T14:07:12.461366 #717]  INFO -- : Writing /apps/baukis2/public/assets/staff-11e27d3f6895cbb72541815d7588bf06f98221a2e8f42d1be3bdbe11275393ab.css.gz
I, [2020-02-23T14:07:12.469250 #717]  INFO -- : Writing /apps/baukis2/public/assets/admin-6a389a316de850fa63407f6a6f065a17c4051e3d3a652ffe61817dc3b459d6ae.css.gz
I, [2020-02-23T14:07:12.473891 #717]  INFO -- : Writing /apps/baukis2/public/assets/customer-a4234a2bf630e8467b2e188d3e87ae6d12995ac013abc703d953f31fa953193e.css.gz
I, [2020-02-23T14:07:12.477312 #717]  INFO -- : Writing /apps/baukis2/public/assets/staff-11e27d3f6895cbb72541815d7588bf06f98221a2e8f42d1be3bdbe11275393ab.css.gz
Compiling...
Compiled all packs in /apps/baukis2/public/packs
Hash: 86f7f0b8c8e4f8885457
Version: webpack 4.41.6
Time: 10749ms
Built at: 02/23/2020 2:07:35 PM
                                       Asset       Size  Chunks                         Chunk Names
      js/application-b973976b9a0d931abb64.js   69.2 KiB       0  [emitted] [immutable]  application
   js/application-b973976b9a0d931abb64.js.gz   17.7 KiB          [emitted]              
  js/application-b973976b9a0d931abb64.js.map    205 KiB       0  [emitted] [dev]        application
js/application-b973976b9a0d931abb64.js.map.gz     51 KiB          [emitted]              
                               manifest.json  364 bytes          [emitted]              
                            manifest.json.gz  142 bytes          [emitted]              
Entrypoint application = js/application-b973976b9a0d931abb64.js js/application-b973976b9a0d931abb64.js.map
[0] (webpack)/buildin/module.js 552 bytes {0} [built]
[1] ./app/javascript/packs/application.js 742 bytes {0} [built]
[5] ./app/javascript/channels/index.js 205 bytes {0} [built]
[6] ./app/javascript/channels sync _channel\.js$ 160 bytes {0} [built]
   + 3 hidden modules
----------------------------------------

Blocked host: localhostが出た!

画像2


rails6から出るらしい。

https://www.tmp1024.com/articles/solve-blocked-host-of-rails
を参考に解決を試みる。

以下の行を加えればいいみたい。
config.hosts << "localhost"

これでおk?

今度は、下記のエラーが出た

----------------------------------------
error Integrity check failed                                                  
error Found 1 errors.                                                         

========================================
 Your Yarn packages are out of date!
 Please run `yarn install --check-files` to update.
========================================

To disable this check, please change `check_yarn_integrity`
to `false` in your webpacker config file (config/webpacker.yml).

yarn check v1.12.3
info Visit https://yarnpkg.com/en/docs/cli/check for documentation about this command.

Exiting
----------------------------------------

これは、yarn install --check-filesを実行すればいいだけだったな

早速実行!

----------------------------------------
bash-4.4$ yarn install --check-files
yarn install v1.12.3
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.2.11: The platform "linux" is incompatible with this module.
info "fsevents@1.2.11" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning " > webpack-dev-server@3.10.3" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "webpack-dev-server > webpack-dev-middleware@3.7.2" has unmet peer dependency "webpack@^4.0.0".
[4/4] Building fresh packages...
Done in 133.95s.
bash-4.4$ 
----------------------------------------

これでどう?

開発環境で表示されるようになった!

画像3

この2つのエラーはあとでQiitaに載せようかな!

500用エラー表示のためのraiseはapp/controllers/staff/top_controller.rbにあったはずだから消しとく

6.3 403 Forbidden

HTTPステータスコード403は、要求されたリソースがWebサイトに存在するが、何らかの理由でアクセスを拒否されたことを示す。
Baukis2では、権限不足またはIPアドレス制限によるアクセス拒否をこのステータスコードで表現することにする。

6.3.1 例外の捕捉

app/controllers/application_controller.rbを次のように書き換える。

app/controllers/application_controller.rb修正後
----------------------------------------
class ApplicationController < ActionController::Base
 # レイアウトをどのメソッドで決めるか
 layout :set_layout
 
 # エラークラスを定義する
 class Forbidden < ActionController::ActionControllerError; end
 class IpAddressRejected < ActionController::ActionControllerError; end
 
 # StandardErrorがあったら、rescue500メソッドを呼び出す
 rescue_from StandardError, with: :rescue500
 rescue_from Forbidden, with: :rescue403
 rescue_from IpAddresRejected, with: :rescue403
 
 # レイアウトを決めるメソッド
 private def set_layout
   if params[:controller].match(%r{\A(staff|admin|customer)/})
     Regexp.last_match[1]
   else
     "customer"
   end
 end
 # Forbiddenエラーがあったときに呼び出されるメソッド
 private def rescue403(e)
   @exception = e
   render "errors/forbidden", status: 403
 end
 # StandardErrorがあったときに呼び出されるメソッド
 private def rescue500(e)
   render "errors/internal_server_error", status: 500
 end
 
end
----------------------------------------

Forbiddenクラスがあるのは分かる
IpAddressRejectedはなんで必要なんだろう?

ちなForbiddenクラスやIpAddressRejectedクラスを参照するときは
ApplicationController::Forbidenとかで参照しないといけない
やることあるかなぁ?

rescue_fromは定義の順番が大事!
親クラスを先に指定しなくちゃいけない!
これを間違えちゃうとForbiddenがrescue500で表示されちゃう!
なんてめんどくさい・・・!

6.3.2 ERBテンプレートの作成

ERBテンプレートを用意!

touch app/views/errors/forbidden.html.erb新規作成
----------------------------------------
<div id="error">
 <h1>403 Forbiden</h1>
 <p>
   <%=
     case @exception
     when ApplicationController::IpAddressRejected
       "あなたのIPアドレス(#{request.ip})からは利用できません。"
     else
       "指定されたページを閲覧する権限がありません。"
     end
   %>
 </p>
</div>
----------------------------------------

requestはrequestオブジェクトを返すメソッド
request.pathでURLパスを返したりなんかしちゃったりできたりもする

requestオブジェクト
requestオブジェクトは、ActionDispatch::Requestクラスのインスタンスで、クライアントからのリクエストに関する情報を保持するオブジェクト。
urlのパスを返すpath
url全体を返すurl
アクセス元を返すip


6.3.3 動作確認

意図的に例外を引き起こしてみる。

app/controllers/admin/top_controller.rb
----------------------------------------
class Admin::TopController < ApplicationController
 def index
   raise IpAddressRejected
   render action: "index"
 end
end
----------------------------------------

@exception = e
がないとerbでwhenの条件分けが上手く行かなかったから注意!

無事行けた

画像4

app/controllers/admin/top_controller.rbのraiseを忘れずに削除しておく

次に、もう一個のほうをテスト

app/controllers/customer/top_controller.rb
----------------------------------------
class Customer::TopController < ApplicationController
 def index
   raise Forbidden
   render action: "index"
 end
end
----------------------------------------

確認できたら元に戻しておく

6.4 404 Not Found

リソースが見つからない時に出るコード

Baukis2では2つの場合でこのステータスコードを使用してエラー画面を表示する。
クライアントによって指定されたURLパスに対応するルーティングが存在しない場合
指定された条件に合致するレコードがデータベースに存在しない場合

6.4.1 例外 ActionController::RoutingErrorの処理

config/routes.rbに記述されたルーティングのいずれにも当てはまらないようなHTTPリクエストがRailsアプリケーションに届いた時、例外ActionController::RoutingErrorが発生する。

しかし、クラスメソッドrescue_fromは、アクションで発生した例外を捕捉するためのものなので、ルーティング処理の段階で発生する例外を捕捉できない。
そこで、ちょっとした工夫が必要となる。

まず、config/initializersディレクトリに新規ファイルexceptions_app.rbを次のような内容で作成する。

touch config/initializers/exceptions_app.rb

config/initializers/exceptions_app.rb新規作成
----------------------------------------
Rails.application.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
----------------------------------------

次に、errorsコントローラを生成する。

bin/rails g controller errors

----------------------------------------
bash-4.4$ bin/rails g controller errors
Running via Spring preloader in process 1149
     create  app/controllers/errors_controller.rb
     invoke  erb
      exist    app/views/errors
     invoke  rspec
bash-4.4$ 
----------------------------------------

そして、app/controllersディレクトリにできたファイルerrors_controller.rbを次のように書き換える。

app/controllers/errors_controller.rb
----------------------------------------
class ErrorsController < ApplicationController
 layout "staff"
 
 def not_found
   render status:404
 end
 
 def unprocessable_entity
   render status: 422
 end
 
 def internal_server_error
   render status: 500
 end
end
----------------------------------------

そして下記2つのファイルを新規作成する
touch app/views/errors/not_found.html.erb
touch app/views/errors/unprocessable_entity.html.erb

そしてエラーページ用のテンプレートを2つ作成する。

app/views/errors/not_found.html.erb新規作成
----------------------------------------
<div id="error">
 <h1>404 Not Found</h1>
 <p>指定されたページは見つかりません。</p>
 <p class="url"><%= request.env["REQUEST_URI"] %></p>
</div>
----------------------------------------
app/views/errors/unprocessable_entity.html.erb新規作成
----------------------------------------
<div id="error">
 <h1>422 Unprocessable Entity</h1>
 <p>指定されたページは表示できません</p>
</div>
----------------------------------------

これでhttp://localhost:3000/xyzにアクセスしてみる。

画像5

エラー画面が表示されないと思ったけど、理由が分かった。

開発環境ではRoutingErrorの画面が表示されて、
本番環境では自作したエラー画面が表示される仕組みだ!
なるほどね〜

6.4.2 例外 ActiveRecord::RecordNotFoundの処理

ActiveRecord経由でデータベースを検索してレコードが見つからなかったときに例外ActiveRecord::RecordNotFoundが発生することがある。
この場合、Baukis2では「404 Not Found」のエラーページを表示することにする。

たとえば、http://localhost:3000/staff/customers/123は、123というidを持つ顧客の情報を閲覧するためのURL
しかし、123というidを持つ顧客のレコードがまだ存在しないか、あるいは削除されてしまった場合には例外ActiveRecord::RecordNotFoundを発生させる。

なので、rescue_fromで例外ActiveRecord::RecordNotFoundの処理方法を登録する。

app/controllers/application_controller.rb修正後
----------------------------------------
class ApplicationController < ActionController::Base
 # レイアウトをどのメソッドで決めるか
 layout :set_layout
 
 # エラークラスを定義する
 class Forbidden < ActionController::ActionControllerError; end
 class IpAddressRejected < ActionController::ActionControllerError; end
 
 # StandardErrorがあったら、rescue500メソッドを呼び出す
 rescue_from StandardError, with: :rescue500
 rescue_from Forbidden, with: :rescue403
 rescue_from IpAddressRejected, with: :rescue403
 rescue_from ActiveRecord::RecordNotFound, with: :rescue404
 
 # レイアウトを決めるメソッド
 private def set_layout
   if params[:controller].match(%r{\A(staff|admin|customer)/})
     Regexp.last_match[1]
   else
     "customer"
   end
 end
 # Forbiddenエラーがあったときに呼び出されるメソッド
 private def rescue403(e)
   @exception = e
   render "errors/forbidden", status: 403
 end
 
 # RecordNotFoundエラーがあったときに呼び出されるメソッド
 private def rescue404(e)
   render "errors/not_found", status: 404
 end
 # StandardErrorがあったときに呼び出されるメソッド
 private def rescue500(e)
   render "errors/internal_server_error", status: 500
 end
 
end
----------------------------------------

動作確認のために、一時的にcustomer/top#indexアクションを次のように変更する。

app/controllers/customer/top_controller.rb
----------------------------------------
class Customer::TopController < ApplicationController
 def index
   raise ActiveRecord::RecordNotFound
   render action: "index"
 end
end
----------------------------------------

これで、http://localhost:3000/customerにアクセスし、図6.6のようなエラー画面が表示されればOK

画像6

イイネ!


6.5 エラー処理モジュールの抽出

ApplicationControllerがごちゃごちゃしてきた

6.5.1 抽出対象のコード

本節では、ActiveSupport::Concernという仕組みを利用して、あるクラスからコードの一部を別のモジュールに抽出する方法について学ぶ

6.5.2 ErrorHandlersモジュールの作成

実はapp/controllersディレクトリには既にconcernフォルダがある。
なので新規ファイル作成するだけでよい。

touch app/controllers/concerns/error_handlers.rb

app/controllers/concerns/error_handlers.rb新規作成
----------------------------------------
module ErrorHandlers
 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
 
 # ForbiddenエラーかIpAddressRejectedがあったときに呼び出されるメソッド
 private def rescue403(e)
   @exception = e
   render "errors/forbidden", status: 403
 end
 
 # RecordNotFoundエラーがあったときに呼び出されるメソッド
 private def rescue404(e)
   render "errors/not_found", status: 404
 end
 # StandardErrorがあったときに呼び出されるメソッド
 private def rescue500(e)
   render "errors/internal_server_error", status: 500
 end
end
----------------------------------------

concernディレクトリに置くモジュールには必ず
extend ActiveSupport::Concern
という記述を加える。
そうすることにより、2つの特性が付与される。

1.include利用可能になる
ErrorHandlersモジュールを読み込んだクラスのメソッド扱いにできる。素敵!
ただし!ForbiddenとIpAddressRejectedはApplicationControllerをつけたよ!
外側に出ちゃったから当然だね!

2.ClassMethods利用可能になる
ClassMethodsというクラスを定義しておくと、そのメソッドがモジュールを読み込んだクラスのクラスメソッドとして取り込まれる。
ただ今回は使ってない。

6.5.3 ApplicationControllerの書き換え

さっそくmodule ErrorHandlersをApplicationControllerに読み込んでみよう!

app/controllers/application_controller.rb
----------------------------------------
class ApplicationController < ActionController::Base
 # レイアウトをどのメソッドで決めるか
 layout :set_layout
 
 # エラークラスを定義する
 class Forbidden < ActionController::ActionControllerError; end
 class IpAddressRejected < ActionController::ActionControllerError; end
 
 # ErrorHandlersメソッドを読み込む
 include ErrorHandlers
 
 # レイアウトを決めるメソッド
 private def set_layout
   if params[:controller].match(%r{\A(staff|admin|customer)/})
     Regexp.last_match[1]
   else
     "customer"
   end
 end
end
----------------------------------------

ApplicationControllerは汚くなりがちだから早めに綺麗にするのをオススメ

本章で用意したエラー処理は本番環境用
developmentとtestではオリジナルのエラー画面が表示されたほうが、開発を進めやすい。

なので、application_controller.rbを次のように書き換える。

app/controllers/application_controller.rb修正後
----------------------------------------
:
 # ErrorHandlersメソッドを読み込む
 include ErrorHandlers if Rails.env.production?
:
----------------------------------------

最後に、冒頭で変更したconfig/environments/production.rbの設定を元に戻す。

config/environments/production.rb修正後
----------------------------------------
:
 # Code is not reloaded between requests.
 config.cache_classes = true
:
----------------------------------------

次章以降では、原則としてdevelopmentモードでアプリケーションを起動して動作確認を行う。


この記事が気に入ったらサポートをしてみませんか?