Railsのコントローラーについて

# 概要
Railsアプリケーションの**コントローラー**について解説してみたいと思います。

# 今回のゴール
**『MVCモデルについて知る』**・**『コントローラーの役割について』**・**『実践的な使い方』**をついて確認することです。

# １. MVCモデルとは
アプリケーションを作成する時に、コードを上手に管理するための考え方のひとつです。
あくまで考え方のひとつなので、絶対的に正しいというものではありません。
Railsアプリケーションは、このMVCフレームワークを取り入れています。

## MVCの３要素
**『Model』**・**『View』**・**『Controller』**になります。
　
・`Model`　・・・　システムの中でビジネスロジックを担当する

・`View`　・・・　 表示や入出力といった処理をする

・`Controller`　・・・　ユーザーの入力に基づき，ModelとViewを制御する

## RailsにおけるMVCの処理の流れ

1. クライアントからのリクエストを**『Controller』**が受け取る

2. **『Controller』**は**『Model』**にデータ処理をお願いする

3. **『Model』**はデータベースからデータを処理し、**『Controller』**にデータを返す

4. **『Controller』**は**『View』**に受け取ったデータの処理をお願いする

5. **『View』**はクライアントが見るのに適した形(HTML文書)を作成し**『Controller』**に返す

6. **『Controller』**はクライアントにHTML文章をレスポンスとして返す

1〜６を繰り返すことにより、Webアプリケーションとして成り立っています。


# 2. コントローラーの役割について
**結論**
・ルーティングから送られた情報をもとに、指定されたコントローラーの**アクションメソッド**を実行すること
・**Model・Viewと連携して**、クライアントにレスポンスを返すこと

## アクションメソッド
ルーティングから指定されたアクションの具体的な処理内容を記述したメソッドです。

```ruby:アクションメソッドのイメージ
class SamplesController < ApplicationController
  def index
    # 具体的な処理内容
    ......
    ......
  end
end
```

今回の例ですと...
ルーティングでsamplesコントローラーのindexアクションが指定された時、実行するアクションメソッドを`def index...end`という形で記述します。

## Modelとの連携について
### 目的
モデルを介して、データベースの新規作成や変更や取得をすることです。

### 方法
モデルが継承しているActiveRecord クラスのメソッドを使い、モデルに指示を出します。
下記はメソッドの一部の例になります。

|メソッド|内容|
|:-:|:--|
|all|データベースの全てのデータを取得する|
|find|データベース内の、ある1つのデータを取得する|
|new |データの新規作成を生成する|
|save|データベースにデータを保存する|

```:メソッドのイメージ
  (モデルクラス名).[メソッド]
  Sample.all
```

## Viewとの連携について
### 目的
モデルから受け取ったデータをビューに渡し、クライアントに返すレスポンスデータを作成することです。

### 方法
モデルからのデータをインスタンス変数を代入します。

```
  @samples = Sample.all
```

これにより、ビューファイルでデータを使えるようになります。

# 3. 実践的な使い方
## コントローラーの設定場所
`app/controllers`ディレクトリ内に
`コントローラー名_controller.rb`ファイルを設定します。

## コントローラーの命名規制
基本的に**『複数形』**にします。
理由は、Railsが使用するファイルなどを名前によって自動的に推測するからです。
仮に単数形にもできますが、開発者自身で明示的にコード記述しなければいけなかったり、予期せぬエラーのもとになってしまいます。

|名称|例|備考|
|:--|:--|:-:|
|コントローラー名|samples||
|コントローラークラス名|SamplesController|キャメルケース|
|コントローラーファイル名|samples_controller.rb|スネークケース|

## コントローラーファイルの構造
コントローラーファイルの中身は、このようになっています。

```ruby:app/controllers/samples_controller.rb
  class SamplesController < ApplicationController
    def index
      # 具体的な処理内容
      ......
      ......
    end
  end
```

作成したコントローラーファイルは**『ApplicationControllerクラス』**を継承します。
　
### ApplicationControllerクラスとは

```ruby:app/controllers/application_controller.rb
  class ApplicationController < ActionController::Base
  end
```

`app/controllers/application_controller.rb`ファイルに定義されたクラスです。
**ActionController::Baseクラス**を継承しただけの、（ほとんど）空のクラスになります。

原則、各コントローラーは、ApplicationControllerクラス継承しているので
アプリケーション共通の機能(ログイン・ログアウトなど)が必要な場合に使用します。
　
### ActionController::Baseクラスとは
コントローラーの基本的な機能を提供するクラスです。
リクエスト／レスポンス処理に関わる基盤部分を担っています。

## HTTPリクエストのパラメータの処理
コントローラーでは、クライアントからのHTTPリクエストのパラメータを**『paramsメソッド』**を経由して取得しています。

### paramsメソッド
Railsが暗黙的に**リクエストパラメータ**を処理して、ハッシュ形式でデータをparamsに格納してくれるメソッドです。
**GETリクエスト・POSTリクエスト**によるアクセスでも、データの受け取り方に違いはありません。

#### GETリクエストによるアクセス
HTTPリクエストのリクエストラインの**『リクエストURI』**にパラメータを含め、Webサーバにアクセスします。
**『URL形式』**と**『クエリ形式』**でパラメータを渡すことができます。
　

##### URL形式
下記のルーティング設定があった時に

```
  Prefix Verb   URI Pattern               Controller#Action
  user   GET    /users/:id(.:format)      users#show
```

`http://sample.com/users/7`というURLでアクセスすると
リクエストの`:id`のパラメータは`7`という意味になり
Rails内ではparamsに格納され`params[:id]`の値は`"7"`となります。

```ruby:app/controllers/users_controller.rb
  class UsersController < ApplicationController
    def show
      params[:id] # "7"
    end
  end
```
　

##### クエリ形式
URLの最後に「?」に続けて「パラメータ名=値」を記述します。
複数のパラメータがある場合は「&」でつなげて記述します。
　
上記の例の同じルーティングを利用し
`http://sample.com/users/7?keyword=query&num=10`というURLでアクセスすると
`params[:keyword]`の値は`"query"`、`params[:num]`は`"10"`となります。

```ruby:app/controllers/users_controller.rb
  class UsersController < ApplicationController
    def show
      params[:keyword] # "query"
      params[:num] # "10"
    end
  end
```
　

#### POSTリクエストによるアクセス
クライアントがフォームからの入力で「送信」ボタンを押した場合などに発生するリクエストです。
HTTPリクエストの**『ボディ』**にパラメータを含め、Webサーバにアクセスします。

またGETリクエストに比べて、多くのパラメータを送信することができます。
　

### paramsを保存する時の注意点
『params』をデータベースに保存する時は、**『Strong Parameters』**という仕組みを使います。

#### Strong Parametersとは
Rails3系まで使われていた『Mass Assignment』の脆弱性を解消するための仕組みです。
『Mass Assignment』では、**モデル**に保存に関するparamsの情報を記述していましたが
『Strong Parameters』では、**コントローラー**に保存するparamsの情報を記述します。

```ruby:Strong_Parametersのイメージ
  class UsersController < ApplicationController
    def create
      @user = User.new(user_params) # user_paramsメソッドを使って、データの新規作成
      @user.save # モデルを介して、データベースに保存する
    end

    # Strong Parametersはクラス外部から呼び出さないので、privateメソッドに記述する
    private
    def user_params
      params.require(:user).permit(:name, :age)
    end
  end
```

今回の例ですと
`user_params`メソッドで、保存するパラメータを`:user`の`:name`と`:age`に指定しています。

##### requireメソッド
データベースに保存するテーブル名を指定します。

##### permitメソッド
データベースのテーブルに保存するカラム名を指定します。
***
コントローラーの解説は以上になります。
ありがとうございました。