概要
Rails 4 からストロングパラメータと言う新機能が導入されました。
具体的には require と permit と言うメソッドのことです。
Scaffold で Controller を作成する際にデフォルトで適用されるのですが、使い方がよく分からず、いつも削除していました。。
今回、require と permit の使い方を調べてまとめました。
はじめに
「名前」と「メールアドレス」を属性に持つ User モデルを Scaffold で作成してみます。
$ rails generate scaffold User name:string email:string
すると、Controller にストロングパラメータを適用した private メソッドがデフォルトで用意されました。
private
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:name, :email)
end
この user_params こそが、使い方がよく分からず削除していたメソッドです。。
これから順を追って中身を説明していきます。
params の中身を確認
初めに params の中身を確認します。
curl コマンドで user ハッシュを POST した結果は以下になります。
$ curl -X POST 'http://localhost/users' -H "Content-Type: application/json" -d '{"user":{"name":"aaa","email":"bbb"}}'
{
"action" : "create",
"user" : {
"name" : "aaa",
"email" : "bbb"
},
"controller" : "users"
}
返り値を見ると controller 名や action 名などもパラメータに含まれていることが分かります。
これがリクエストを投げたときの全ての返り値です。
params.require の中身を確認
次に params.require( :user ) の中身を確認します。
先ほどと同じように user ハッシュを POST した結果が以下になります。
$ curl -X POST 'http://localhost/users' -H "Content-Type: application/json" -d '{"user":{"name":"aaa","email":"bbb"}}'
{
"name" : "aaa",
"email" : "bbb"
}
user ハッシュの値だけになりましたね!
require メソッドを利用することで、引数に設定した key の 値だけを取得することができます。
余談ですが、、、
params.require( :controller ) とすれば "users" が取得できます。
params.require( :action ) とすれば "create" が取得できます。
params.require.permit の中身を確認
最後に params.require( :user ).permit( :name, :email ) の中身を確認します。
params.require( :user ) のままでは、user ハッシュの全ての値を取得してしまいます。
そこで permit( :name, :email ) を利用します。
permit メソッドは許可したいパラメータだけをフィルタしてくれます。
例えば、User モデルに存在しない「電話番号」を一緒に POST したとしても、許可されていないので返り値に存在しません。
$ curl -X POST 'http://localhost/users' -H "Content-Type: application/json" -d '{"user":{"name":"aaa","email":"bbb","tel":"111"}}'
{
"name" : "aaa",
"email" : "bbb"
}
これは API を作成する場合など、予期せぬパラメータの付与を避けたい場合に非常に便利です。
おまけ
配列のパラメータを受け取りたい場合
ちなみに「メールアドレス」が複数ある場合など、配列でパラメータを受け取りたい場合は以下のように記載します。
private
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:name, email: []) # 配列の場合
end
user ハッシュを POST して見ると、以下のような返り値が取得できます。
$ curl -X POST 'http://localhost/users' -H "Content-Type: application/json" -d '{"user":{"name":"aaa","email":["aa","bb","cc"]}}'
{
"name" : "aaa",
"email" : [
"aa",
"bb",
"cc"
]
}
まとめ
3 段階に分けて返り値を確認しました。
- params の中身を確認
- params.require の中身を確認
- params.require.permit の中身を確認
返り値を比べることで require と permit メソッドの役割が分かったかなと思います。
基本的には create や update メソッドで 今回のストロングパラメータが使われることが多いです。
ストロングパラメータは mass assignment 脆弱性の対策に導入されたと言われています。ユーザ操作によって本来更新すべきでないカラムが更新されるのを防ぐためです。
ストロングパラメータを利用して安全で綺麗なコードを書きましょう。