RailsのStrong Parametersを完全解説!ネスト・配列・ハッシュのpermit書き方パターンまとめ
生徒
「Railsのパラメータって、どうやって安全に受け取ればいいんですか?」
先生
「Railsでは、Strong Parameters(ストロングパラメータ)という仕組みを使って、受け取るパラメータを明示的に制限できます。」
生徒
「ネストされたデータや配列も扱えるんですか?」
先生
「もちろん!ネストや配列もバッチリ対応できますよ。今回はその書き方を詳しく学んでいきましょう。」
1. Strong Parameters(ストロングパラメータ)とは?
Strong Parametersとは、Railsのセキュリティ機能のひとつで、ユーザーから送られてくるパラメータのうち、どれを許可(permit)するかを明確に定義する仕組みです。これにより、意図しない値の更新や、マスアサインメント脆弱性を防ぐことができます。
マスアサインメントとは、送られてきたすべてのパラメータがモデルに一括で代入されてしまう危険な状態のこと。Strong Parametersを使えば、それを防げるのです。
2. ネストされたパラメータのpermit書き方
フォームやAPIで送られてくるデータは、ネストされた構造(入れ子構造)になっていることがあります。たとえば、以下のような場合です。
params = {
user: {
name: "山田太郎",
address: {
city: "東京",
zip: "100-0001"
}
}
}
このようなときは、次のようにpermitを記述します。
params.require(:user).permit(:name, address: [:city, :zip])
address: [:city, :zip]のように、ネストしたハッシュにはシンボルのキーと配列で許可する項目を記述します。
3. 配列のパラメータをpermitする方法
チェックボックスで複数選択された値や、タグなどの情報は配列として送られてくることがあります。例を見てみましょう。
params = {
article: {
title: "Rails入門",
tags: ["Ruby", "Rails", "Web"]
}
}
このときのpermitの書き方は以下のとおりです。
params.require(:article).permit(:title, tags: [])
tags: []のように、空の配列を渡すことで、どんな値でもOKな配列を許可する意味になります。
4. 配列の中身がハッシュの場合
さらにレベルアップした例として、「配列の中にハッシュが入っている」ケースもあります。これは複数の項目をまとめて送信する場面でよく使われます。
params = {
order: {
items: [
{ name: "りんご", quantity: 3 },
{ name: "バナナ", quantity: 5 }
]
}
}
この場合のpermitの書き方はこうなります。
params.require(:order).permit(items: [:name, :quantity])
items: [:name, :quantity]のように、配列の中のハッシュの項目を指定するだけで、複雑な構造でも簡単に許可できます。
5. ネスト+配列+ハッシュの複合パターン
次はさらに複雑な「ネストされた中に配列があり、その配列の中身がハッシュ」になっているパターンです。
params = {
customer: {
name: "佐藤花子",
contacts: {
phones: [
{ type: "自宅", number: "090-1234-5678" },
{ type: "会社", number: "03-1234-5678" }
]
}
}
}
こうした構造のときでも、permitで柔軟に対応できます。
params.require(:customer).permit(
:name,
contacts: {
phones: [:type, :number]
}
)
contacts: { phones: [:type, :number] }のように、ネストの中にある配列の中のハッシュをpermitでしっかり指定しましょう。
6. permitしないとどうなる?
Strong Parametersでpermitしないと、Railsはパラメータをフィルタして破棄します。つまり、意図的に許可しないと、モデルに値が保存されないことになります。
また、requireを忘れるとエラーが発生することもあります。
ActionController::ParameterMissing (param is missing or the value is empty: user)
このようなエラーが出たときは、params.require(:user)のように書いてあるかどうかを確認しましょう。
7. よくあるStrong Parametersの書き方パターン一覧
ここまでの内容をもとに、よく使うパターンを一覧でおさらいしておきましょう。
| パターン | permitの書き方 |
|---|---|
| 単純な属性 | .permit(:name, :email) |
| ネストされたハッシュ | .permit(address: [:city, :zip]) |
| 配列 | .permit(tags: []) |
| 配列の中のハッシュ | .permit(items: [:name, :price]) |
| ネスト+配列+ハッシュ | .permit(contacts: { phones: [:type, :number] }) |