Ruby on Rails6 実践ガイド cp4~cp6 【メモ】

## はじめに
この記事の筆者はプログラミングを学習し始めたばかりの初心者です。間違いがあれば指摘していただけると幸いです。

## 概要
この記事は[Ruby on Rails6 実践ガイド](https://book.impress.co.jp/books/1118101134)を読んで学んだことを自分用のメモとして記録したものです。抜粋してピックアップするので読みづらいと思われます。すいません。
この本には、続編の[機能拡張編](https://book.impress.co.jp/books/1118101135)もあり、記事を書いている段階で二冊とも学習を終えています。復習もかねて記事を書いていくつもりです。
18のチャプターに分かれているので、見出しごとに区切っていきます。
Chapter3までは環境構築がメインなので飛ばしています。

# Chapter4 RSpec

[skipとpendingは何が違うのか?【RSpec】](https://qiita.com/nizi24/items/bddeca0379a4d11a5240)
# Chapter5 ビジュアルデザイン
### namespace

```ruby:routes.rb
namespace :staff do
  root "top#index"
end
```
namespaceは名前空間を設定するメソッドです。上の例ではrootのパスは /staff になります。
コントローラーはStaff::TopControllerになります。

### render

```ruby:staff/top_controller.rb
  def index
    render action: "index"
  end
```

renderは、HTML文書を生成するメソッドです。
render action: "index" は省略可能です。


```ruby:staff/top_controller.rb
  def index
  end
```
render等を用いればアクションに対応するテンプレート以外を用いることもできます。本書の後半ではそのような使い方もされていました。

### present?

present?はblank?の否定。Railsによって追加されたObjectクラスのインスタンスメソッド。

### layout

```ruby: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
end
```

layoutメソッドでレイアウトを決定するためのメソッドを指定することができます。上記の例では名前空間ごとに動的にレイアウトを切り替えています。

# Chapter6 エラーページ

### rescue_from

```ruby:application_controller.rb
rescue_from Forbidden, with: :rescue403
```

>これをApplicationControllerクラスの定義の中で定義すれば、任意のアクションにおいて例外Forbidden(あるいはその子孫にあたる例外)が発生したときに、アクションが中断されて、メソッドrescue403に処理が移行します。


```ruby:application_controller.rb
#メソッドrescue403の実装例
private def rescue403(e)
  @exception = e
  render template: "errors/forbidden", status: 403
end
```

##### テンプレートの例(一部抜粋)

```haml:forbidden.html.haml
- case @exception
- when ApplicationController::IpAddressRejected
  "あなたのIPアドレス(#{request.id})からは利用できません。"
- else
  "指定されたページを閲覧する権限がありません。"
```

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

#### ActiveSupport::Concern
ActiveSupport::Concernという仕組みを用いると、あるクラスからコードの一部を別のモジュールに抽出することができます。

```ruby:concerns/error_handlers.rb
module ErrorHandlers
  extend ActiveSupport::Concern

  included do
    rescue_from ApplicationController::Forbidden, with: rescue403
    #その他のコードは省略
  end

  private def rescue403(e)
    @exception = e
    render "errors/forbidden", status: 403
  end
  #その他のコードは省略
end
```

concernsディレクトリに置くモジュールには

```ruby
extend ActiveSupport::Concern
```

の記述が必要です。その結果includedメソッドが利用可能になります。
このメソッドはブロックを取り、ブロック内のコードがこのモジュールを読み込んだクラスの文脈で評価されるようになります。

もう一つの性質として、このモジュールのサブクラスとしてClassMethodsというクラスを定義しておくと、そのメソッドがモジュールを読み込んだクラスのクラスメソッドとして取り込まれるという性質もありますが、今回は使用されていませんでした。

#### コードを実行する環境を限定する

```ruby:application_controller.rb
include ErrorHandlers if Rails.env.production?
```

includeする環境を限定して、本番環境以外ではオリジナルのエラー画面が表示されるようにしています。

## 続き
続きの記事のURLも順次追加していきます。
[Ruby on Rails6 実践ガイド cp7~cp9 【メモ】](https://qiita.com/nizi24/items/60e7fb846a25830478b9)
[Ruby on Rails6 実践ガイド cp10~cp12 【メモ】](https://qiita.com/nizi24/items/e430cadb57a26a7cff76)
[Ruby on Rails6 実践ガイド cp13~cp15 【メモ】](https://qiita.com/nizi24/items/241e766e7c2afc98292b)
[Ruby on Rails6 実践ガイド cp16~cp18 【メモ】](https://qiita.com/nizi24/items/e83749826f8d70223311)
[Ruby on Rails6 実践ガイド[機能拡張編] cp3~cp6 【メモ】](https://qiita.com/nizi24/items/36da7b89d561c19af30f)
[Ruby on Rails6 実践ガイド[機能拡張編] cp7~cp9 【メモ】](https://qiita.com/nizi24/items/232e4f05f9d416e0a08c)
[Ruby on Rails6 実践ガイド [機能拡張編] cp10~cp12 【メモ】](https://qiita.com/nizi24/items/2ec4ed513fce22a89222)

## 引用元
※マークダウンの引用を用いている部分は以下の書籍から引用しています。
[Ruby on Rails6 実践ガイド](https://book.impress.co.jp/books/1118101134)