*プログラミング超初学者のため、間違いは指摘頂けると大変ありがたいです。
記事の目的
Ruby on Railsでアプリケーション開発を行う際、何かと出てくるこいつ。
調べてわかった気になっては毎回わかってなくて悩まさせれたので、備忘のためにまとめておくものです
1.ストロングパラメータとは
「パラメータを受け取る際に、指定したキーを持つパラメータしか受けとれない様に制限できるもの」
端的にいうと上記の通りです。目的としてはセキュリティ向上のため、といった所でしょうか。
2.もうちょっと具体的に
「指定したキーを持つ」という制限がないとどうなるのでしょうか。
例えばユーザー登録機能を実装していて、登録時に名前、とメールアドレスを求められたとします。
この場合、こちら側が保存したいのは「userテーブルのnameカラム、emailカラムの情報」なのでしょう。
なのでフォームから送られてきたパラメータをうまくnameとemailカラムに保存される様に処理を行います。
ざっくり言うとこんな感じです。
この保存処理の際、簡単にいうと「指定したカラムの情報以外はうけつけませんからね」というのがストロングパラメータです。
例えば登録を行うユーザーに悪意があり、開発側がユーザー登録時に登録されたくないカラムのデータを送ってきた場合等を想定すると必要性がわかります。
善意のユーザーであれば「nameとemailを登録してね」という指示にはそれしか入力してこないでしょうが、悪意あるユーザーであれば「ついでに他人のアカウント情報を閲覧できる権限も自分のレコードに追加しておくね」とかができてしまうわけです。
仮にそんなことをやってきたとしても、ストロングパラメータで「いやnameとemail以外は知らんし」と言っておけば跳ね除けられるわけですね。強い。確かにストロング。
#3 各種メソッドを含めた書き方と考え方
3-1 基本的な書き方
MVCの流れの中で、それぞれのメソッドがどういう役割を果たしているのか記載していきます。
これはチャットシステムでのメッセージ送信時のcreateで使おうとしてる例です。
private
def message_params
params.require(:モデル名).permit(:カラム名1,:2,,,).merge(カラム名: 追加したいデータ値)
end
それぞれの中身について説明していきます。
3-2 require(:モデル名) メソッド
ここにはモデル名を記載します。なんの?、という所なんですが、考え方としては**今回登録したいのはどのテーブルのレコードなの?**という見方です。
今回はmessageをcreateしようとしてるので、キーとしてmessageモデルを使用するわけです。
僕は最初モデル名と丸暗記していて、複数のモデル情報を受け取るパラメータで両方ここで指定するもんだと思ってました。
あくまでこのアクションでcreateしたいテーブルを管轄するmodelを指定するわけですね。
これを踏まえ、上記のコードは
private
def message_params
params.require(:message).permit(:カラム名1,:2,,,).merge(カラム名: 追加したいデータ値)
end
と記載することができます。
3-3 .permit(:カラム名1,:カラム名2,,,) メソッド
こちらがストロングパラメータの説明で記載した、**「どの値を許可して受け入れるか」**を記載する箇所ですね。
根幹の機能ですしpermitって英語なのでめちゃくちゃわかりやすいかと思います。
今回、メッセージを受け取るにあたっては文章の内容をcontentとして受け取るか、画像がアップロードされた場合はimageとして受け取るかの二つのみを指定したいと思います。
踏まえて表記すると、コードは以下の通りになります。
private
def message_params
params.require(:message).permit(:content, :image).merge(カラム名: 追加したいデータ値)
end
3-4 .merge(カラム名: 追加したいデータ値) メソッド
ここです。ここが個人的におお確かにだとなりました。プチアハ体験。
今回のメッセージテーブルには、誰が投稿したメッセージかを識別する「user_id」カラムが存在します。
当然、メッセージをcreateする際にそちらにもデータを保存したいのですが、その値は別にフォームでユーザーに記入してもらうわけではありません(ユーザーからフォームにのっとってパラメーターで送信されてきるわけではありません)
僕らがログイン情報から引っ張ってきて登録すればいいわけです。
この考え方自体は別にストロングパラメータとは関係ありません。
ありませんがストロングパラメータはそもそも**「パラメータで受け取った値をどの程度許可するのか?」**という処理ですから、パラメータ外の値を受けいれることはできないんじゃ?というのが僕の素朴な疑問でした。
ちゃんとあるんですね、mergeメソッドが。
まとめてしまうとmergeメソッドは、「直接的にユーザーから受け取ったparamsにないが、レコード作成時に追加したい値はmergeメソッドで追加しとくと合わせてそれも処理しちゃうよ」ってことですね。
ほんとメソッドってすごい。痒いところに手が届く。
そんなこんなを踏まえてログインユーザーのidを追加する様にコードを記載すると
private
def message_params
params.require(:message).permit(:content, :image).merge(user_id: current_user.id)
end
となるわけです(gem deviseを使用しています)
まとめ
ストロングパラメータは、セキュリティ向上の観点から受け取るパラメータの種別を指定するもの。
require → どのテーブルに関する情報?
permit → 受け取りたい値の指定は?何を?
merge → 他から追加しときたい値は?どこに何を?
という感じで指定することができる。
いざ文にするとあやふやなことばっかだ、、、ご指摘いただければ幸いです、、、