皆さんに質問です。
「ワンピース」は好きですか?
愚問でしたね、私も大好きです。
ワノ国編が面白すぎて「今週号読んだ?神回やわ…」って毎週言ってます笑
ちなみに一番好きなキャラはゾロです。
では次の質問です。
Railsの「ストロングパラメータ」は知ってますか?
「なんとなく、、」
「言葉は知ってるけど、正直何やってるか知らん」
「なにそれ?おいしいの?」
大丈夫です。
そんな人たちに向けて、ワンピースの世界観を題材にしてわかりやすく解説します。
この記事の目標は、
「他の例えを使って説明できるレベルまでストロングパラメータの理解を深める」です。
####それでは早速、冒険に出発しましょう!
##1. パラメータとストロングパラメータを少しおさらい
冒険に行く前に、
まずはパラメータとストロングパラメータの違いについて少しおさらいしておきましょう。
・パラメータ(Parameters 又は Params)
送信される複数のデータをひとまとめにしたモノ
例:Twitterで投稿されるデータ(ユーザー名、ツイート文、画像)
・ストロングパラメータ(Strong Parameter)
上記のパラメータが保存するべきデータかチェックするコト
##2. なぜストロングパラメータが必要なのか
逆にストロングパラメータがない場合を考えてみましょう。
どんな値でも保存されるようになってしまうという事になるのですが、
そうすると悪意のあるユーザーが
管理者であることを証明するデータを追加で保存できてしまう
のです。
つまりどうなるかというと、乗っ取られます。
乗っ取りを防ぐためのストロングパラメータ
なのです。
##3. パラメータは小型船、ストロングパラメータは侵入者チェッカー
※基本的なMVCの流れは割愛します。
それではワンピースの世界観で考えていきましょう。
あなたは赤いダイヤの海賊旗が特徴の、レイルズ海賊団の船長です。
現在、グランドラインを航海中。
新世界に入る前に、新しいクルーを探す事にしました。
欲しいクルーは料理人:cock
と医者:doctor
です
そんな時に様々な人種、職種の人たちが住んでいると言われる島を見つけました。
しかしそこは海賊の入国がNGとのこと。
仕方なく、あなたは海賊船でお留守番。
代わりに既存のクルーたちに小型船で新たなクルーを見つけてきてもらう事にしました。
実際のコードで表してみましょう。
def new("新たなクルーを探しに小型船が出発")
@crew = Crew.new
end
def create("帰船後、新たなクルーを仲間にする")
Crew.create(crew_params)
end
ここで船長のあなたは気をつけるべき点があります。
それは「侵入者を乗船させてはいけない」というところです。
あなたの懸賞金目当てに紛れてくる侵入者を、あなた自身が見分けないといけません。
侵入者を見分ける力を持つミエミエの実。弱そう
その能力者である、あなただけにしかできない事なのです。
あなたの能力はcrew_params
という場所(メソッド)で発揮されます。
仲間にする前に、必ずこの場所を通すよう指示しました。
このcrew_params
こそがストロングパラメータなのです。
新たなクルーとして受け入れるべきかどうかのチェック、
つまり保存する前に正しいデータであるかのチェックですね。
どういった中身なのか見てみましょう。
private
def crew_params
params.require(:crew).permit(:cock, :doctor)
end
一つずつ確認していきましょう。
params...小型船
require...小型船の中にある部屋を指定(今回はcrewという名前)
permit...部屋の中にいる人で、指定の職業のみ仲間として受け入れる
では、ここで実際にストロングパラメータを通る直前のparamsを確認してみましょう。
どうやって確認するのか?
それは、あなたの見聞色の覇気(binding.pry)で確認できます。
早速、仕掛けて確認してみましょう。
private
def crew_params
binding.pry
params.require(:crew).permit(:cock, :doctor)
end
そうすると、ターミナルで下記のように止まります。
今回はparamsを見たいので、次のように入力しましょう。
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
がいるわけです。
この場合だと、ちゃんとデータは保存されます。これで正式な仲間として入団できましたね。
ここでストロングパラメータが不正なデータだと判断し、保存しないパターン例を紹介します。
・permitで指定した名前と異なるデータだった時
部屋の中に侵入者、つまり違う職業のやつが入っていれば仲間として受け入れられません。
・requireを指定しない
職業の指定はしてもどこの部屋にクルー候補がいるかわからない
ので、
あなたは新たなクルーを仲間に加えることができません。
###補足
ストロングパラメータでは下記のように.mergeを付け加えることがあります。
private
def crew_params
params.require(:crew).permit(:cock, :doctor).merge(user_id: current_user.id)
end
これは、paramsのデータにログインしているユーザーIDを付け加えますよって意味です。
今回の話だと、
「新たなクルーを仲間に選んできたのは既存クルーの誰なのか」
Twitterの話だと、
「ツイートしたのは誰なのか」
というデータも必要になってくるからストロングパラメータのついでに付け加えてるんですね。
#まとめ
ストロングパラメータとは、
- 悪意あるユーザからの攻撃を守る
- 保存するべき内容かチェックする
- 保存できていなければ、binding.pryを仕掛けてparamsを要確認
ということですね。
あなたの能力ストロングパラメータ
のおかげで、侵入者を許すことなくレイルズ海賊団のクルー層は強化されました。
これで新世界の準備は整いましたね。
さあ、海賊王になるため、これからもプログラミング学習を頑張ってください!
世はまさに、大プログラミング時代!!!