ONE PIECE FILM STRONG PARAMETERS -ストロングパラメータがわからない人向け-

皆さんに質問です。
「**ワンピース**」は好きですか？
愚問でしたね、私も大好きです。
ワノ国編が面白すぎて「今週号読んだ？神回やわ…」って毎週言ってます笑
ちなみに一番好きなキャラはゾロです。

では次の質問です。
Railsの「**ストロングパラメータ**」は知ってますか？

>「なんとなく、、」
「言葉は知ってるけど、正直何やってるか知らん」
「なにそれ？おいしいの？」

大丈夫です。
そんな人たちに向けて、**ワンピースの世界観を題材にしてわかりやすく解説します。**
この記事の目標は、
「**他の例えを使って説明できるレベルまでストロングパラメータの理解を深める**」です。

####それでは早速、冒険に出発しましょう！

<br>
<br>

##１. パラメータとストロングパラメータを少しおさらい
冒険に行く前に、
まずはパラメータとストロングパラメータの違いについて少しおさらいしておきましょう。


**・パラメータ（Parameters 又は Params）**
送信される複数のデータをひとまとめにしたモノ
例：Twitterで投稿されるデータ（ユーザー名、ツイート文、画像）

**・ストロングパラメータ（Strong Parameter）**
上記のパラメータが保存するべきデータかチェックするコト


##2. なぜストロングパラメータが必要なのか
逆にストロングパラメータがない場合を考えてみましょう。

どんな値でも保存されるようになってしまうという事になるのですが、
そうすると悪意のあるユーザーが
``管理者であることを証明するデータを追加で保存できてしまう``のです。
つまりどうなるかというと、**乗っ取られます。**
乗っ取りを防ぐための`ストロングパラメータ`なのです。

##3. パラメータは小型船、ストロングパラメータは侵入者チェッカー
※基本的なMVCの流れは割愛します。

それではワンピースの世界観で考えていきましょう。
あなたは赤いダイヤの海賊旗が特徴の、**レイルズ海賊団の船長**です。
現在、グランドラインを航海中。
新世界に入る前に、新しいクルーを探す事にしました。
欲しいクルーは`料理人：cock`と`医者：doctor`です

そんな時に様々な人種、職種の人たちが住んでいると言われる島を見つけました。
しかしそこは海賊の入国がNGとのこと。
仕方なく、あなたは海賊船でお留守番。
代わりに既存のクルーたちに小型船で新たなクルーを見つけてきてもらう事にしました。

実際のコードで表してみましょう。


```ruby:crews_controller.rb
  def new("新たなクルーを探しに小型船が出発")
    @crew = Crew.new
  end

  def create("帰船後、新たなクルーを仲間にする")
    Crew.create(crew_params)
  end
```
ここで船長のあなたは気をつけるべき点があります。

それは「**侵入者を乗船させてはいけない**」というところです。

あなたの懸賞金目当てに紛れてくる侵入者を、あなた自身が見分けないといけません。
侵入者を見分ける力を持つミエミエの実。~~弱そう~~
その能力者である、あなただけにしかできない事なのです。

あなたの能力は`crew_params`という場所（メソッド）で発揮されます。
仲間にする前に、必ずこの場所を通すよう指示しました。
この`crew_params`こそが**ストロングパラメータ**なのです。

新たなクルーとして受け入れるべきかどうかのチェック、
つまり**保存する前に正しいデータであるかのチェック**ですね。

どういった中身なのか見てみましょう。

```ruby:crews_controller.rb
  private
  def crew_params
    params.require(:crew).permit(:cock, :doctor)
  end
```
一つずつ確認していきましょう。
> **params**...小型船
**require**...小型船の中にある部屋を指定（今回はcrewという名前）
**permit**...部屋の中にいる人で、指定の職業のみ仲間として受け入れる


では、ここで実際にストロングパラメータを通る直前のparamsを確認してみましょう。

どうやって確認するのか？
それは、あなたの見聞色の覇気（**binding.pry**）で確認できます。
早速、仕掛けて確認してみましょう。

```ruby:crews_controller.rb
  private
  def crew_params
    binding.pry
    params.require(:crew).permit(:cock, :doctor)
  end
```

そうすると、ターミナルで下記のように止まります。
今回はparamsを見たいので、次のように入力しましょう。

```ruby:ターミナル

    44: def crew_params
 => 45:   binding.pry
    46:   params.require(:crew).permit(:cock, :doctor)
    47: end

[1] pry(#<CrewsController>)> params
=> <ActionController::Parameters {"authenticity_token"=>"nZfbXYrhx2pnenZi47nJFcFR7yrVxFyL95P8qTwg4xtoZHWMQk7jqahnqa3Z1e6og+wkobp+m0M+hHRmBWwjbA==", "crew"=>{"cock"=>"私は料理人です", "doctor"=>"私は医者です"}, "commit"=>"SEND", "controller"=>"crews", "action"=>"create"} permitted: false>
```
ちょっと横に長いのでスクロールして確認して欲しいですのですが、
**Parametersというカッコ{}の中に、crewというカッコ{}が入れ子**のように入ってますよね？
crewという部屋の中に、新たなクルー候補の`cock`と`doctor`がいるわけです。
この場合だと、ちゃんとデータは保存されます。これで正式な仲間として入団できましたね。
<br>
ここで**ストロングパラメータが不正なデータだと判断し、保存しない**パターン例を紹介します。

**・permitで指定した名前と異なるデータだった時**
部屋の中に侵入者、つまり違う職業のやつが入っていれば仲間として受け入れられません。

**・requireを指定しない**
職業の指定はしても`どこの部屋にクルー候補がいるかわからない`ので、
あなたは新たなクルーを仲間に加えることができません。


<br>


###補足
ストロングパラメータでは下記のように.mergeを付け加えることがあります。

```ruby:crews_controller.rb
  private
  def crew_params
    params.require(:crew).permit(:cock, :doctor).merge(user_id: current_user.id)
  end
```

これは、**paramsのデータにログインしているユーザーIDを付け加えますよ**って意味です。

今回の話だと、
「新たなクルーを仲間に選んできたのは既存クルーの誰なのか」
Twitterの話だと、
「ツイートしたのは誰なのか」

というデータも必要になってくるから**ストロングパラメータのついでに付け加えてる**んですね。


#まとめ
ストロングパラメータとは、

* **悪意あるユーザからの攻撃を守る**
* **保存するべき内容かチェックする**
* **保存できていなければ、binding.pryを仕掛けてparamsを要確認**

ということですね。

あなたの能力`ストロングパラメータ`のおかげで、侵入者を許すことなくレイルズ海賊団のクルー層は強化されました。
これで新世界の準備は整いましたね。

さあ、海賊王になるため、これからもプログラミング学習を頑張ってください！
世はまさに、大プログラミング時代！！！