Rails 8 API: ActionController::Parameters
(翻訳)
ActionController::Parameters
は、マスアップデートでどの属性の更新を許可するかを指定できるようにし、それによって本来公開されてはならない属性が誤って公開されることを防ぎます。
ActionController::Parameters
は、パラメータをフィルタで除外したり、パラメータを省略不可(必須化)にしたりするために、以下のメソッドを提供します。
expect
- パラメータの許可と必須化を1回のステップで安全に完了できます。
permit
- パラメータをフィルタで除外してマスアサインメントを防止します。
require
- パラメータを省略不可にし、省略された場合はエラーをraiseします。
利用例:
params = ActionController::Parameters.new({
person: {
name: "Francesco",
age: 22,
role: "admin"
}
})
permitted = params.expect(person: [:name, :age])
permitted
# => #<ActionController::Parameters {"name"=>"Francesco", "age"=>22} permitted: true>
Person.first.update!(permitted)
# => #<Person id: 1, name: "Francesco", age: 22, role: "user">
Parameters
は、新しいインスタンスにおけるトップレベルの振る舞いを制御するために、以下の2つのオプションを提供しています。
permit_all_parameters
true
に設定すると、デフォルトですべてのパラメータが許可されます(デフォルトはfalse
)。action_on_unpermitted_parameters
- 明示的に許可していないパラメータが見つかった場合の振る舞いを制御します。development環境とtest環境のデフォルト値は
:log
です。それ以外の環境ではfalse
に設定されます。以下の値を指定できます。
-false
: 何も行いません。
-:log
:ActiveSupport::Notifications.instrument
イベントをunpermitted_parameters.action_controller
というトピックでDEBUGレベルでログ出力します。
-:raise
:ActionController::UnpermittedParameters
例外をraiseします。
実行例:
params = ActionController::Parameters.new
params.permitted? # => false
ActionController::Parameters.permit_all_parameters = true
params = ActionController::Parameters.new
params.permitted? # => true
params = ActionController::Parameters.new(a: "123", b: "456")
params.permit(:c)
# => #<ActionController::Parameters {} permitted: true>
ActionController::Parameters.action_on_unpermitted_parameters = :raise
params = ActionController::Parameters.new(a: "123", b: "456")
params.permit(:c)
# => ActionController::UnpermittedParameters: found unpermitted keys: a, b
これらのオプションはスレッド安全ではない点にご注意ください。マルチスレッド環境でこれらを設定する場合は起動時に1回だけにすべきであり、以後実行中に変更してはいけません。
ActionController::Parameters
の値は、以下のように :key
(シンボルキー)でも"key"
(文字列キー)でも取り出せます。
params = ActionController::Parameters.new(key: "value")
params[:key] # => "value"
params["key"] # => "value"
🔗 定数
🔗 PERMITTED_SCALAR_TYPES
以下の許可済みスカラー型のリストは、XMLリクエストやJSONリクエストでサポートされているものを含みます。
PERMITTED_SCALAR_TYPES = [
String,
Symbol,
NilClass,
Numeric,
TrueClass,
FalseClass,
Date,
Time,
# DateTimesはDatesであり、型としてここにドキュメント化しているが、余分なチェックは避けている
StringIO,
IO,
ActionDispatch::Http::UploadedFile,
Rack::Test::UploadedFile,
]
このリストは特に、通常のリクエストをフィルタリングするときに使われます。String
型は、一般的なケースを迅速にショートカットするための最初の要素として使われます。
このコレクションを変更する場合は、permit
のドキュメントに記載されるコレクションも更新すること。
🔗 クラスpublicメソッド
🔗 new(parameters = {}, logging_context = {})
ActionController::Parameters
の新しいインスタンスを返します。このインスタンスで設定されるpermitted
属性のデフォルト値は、permit_all_parameters
の設定に従います。
class Person < ActiveRecord::Base
end
params = ActionController::Parameters.new(name: "Francesco")
params.permitted? # => false
Person.new(params) # => ActiveModel::ForbiddenAttributesError
ActionController::Parameters.permit_all_parameters = true
params = ActionController::Parameters.new(name: "Francesco")
params.permitted? # => true
Person.new(params) # => #<Person id: nil, name: "Francesco">
🔗 インスタンスpublicメソッド
🔗 ==(other)
別のParameters
オブジェクトと比較したときに、オブジェクトのコンテンツとpermitted
フラグの設定が同じであればtrue
を返します。
🔗 [](key)
指定のkey
に対応するパラメータを返します。パラメータが見つからない場合はnil
を返します。
params = ActionController::Parameters.new(person: { name: "Francesco" })
params[:person] # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
params[:none] # => nil
🔗 []=(key, value)
指定されたkey
に値を代入します。ここで指定したキーは、permit
が呼び出されたときに引き続きフィルタで除外される可能性があります。
🔗 as_json(options=nil)
パラメータのJSON表現として利用できるハッシュを返します。
🔗 compact()
nil
値を削除したActionController::Parameters
の新しいインスタンスを返します。
🔗 compact!()
nil
値を削除したself
を返す破壊的メソッドです。変更が発生しなかった場合はnil
を返します。
🔗 compact_blank()
空白値を含まない新しいActionController::Parameters
インスタンスを返します。値が空白かどうかはObject#blank?
メソッドで判定されます。
🔗 compact_blank!()
空白値をすべて削除したself
を返す破壊的メソッドです。値が空白かどうかはObject#blank?
メソッドで判定されます。
🔗 converted_arrays()
permit
とマスアサインメントの一般的なユースケースで二重ループを書かずに済むよう、変換済み配列をトラッキングする属性です(内部用)。必要な時だけインスタンス化するためにメソッドで定義します。
Testing
によるメンバーシップの存在チェックのループが解消されるわけではありませんが、独自のループで値を変換するよりも高速です。また、フェッチのたびに配列オブジェクトを新たにビルドすることがなくなります。
🔗 deep_dup()
ActionController::Parameters
インスタンスの複製を返します。返されるインスタンスのpermitted
パラメータは元と同じ値になります。
🔗 deep_merge(other_hash, &block)
self
とother_hash
を再帰的にマージする形で、ActionController::Parameters
の新しいインスタンスを返します。
Ruby標準ライブラリのHash#merge
と同様に、マージの値にはブロックも渡せます。
🔗 deep_merge!(other_hash, &block)
self
を改変すること以外は#deep_merge
と同じです。
🔗 deep_transform_keys(&block)
個別のキーに対してblock
を1回ずつ実行した結果を含む、ActionController::Parameters
の新しいインスタンスを返します。これにはrootハッシュのキーも、ネストしたハッシュや配列のキーもすべて含まれます。値は変更されません。
🔗 deep_transform_keys!(&block)
キーを破壊的に変更したActionController::Parameters
の同じインスタンスを返します。これにはrootハッシュのキーも、ネストしたハッシュや配列のキーもすべて含まれます。値は変更されません。
🔗 delete(key, &block)
Parameters
からキーバリューペアを1個削除してから、削除した値を返します。key
が見つからない場合はnil
を返します(オプションのコードブロックを渡した場合は、key
を生成して結果を返します)。このメソッドは、対応するActionController::Parameters
オブジェクトを返す extract!
に似ています。
🔗 delete_if(&block)
reject!
のエイリアスです。
🔗 dig(*keys)
ステップごとにdig
を呼び出すことで、指定のキーからネステッドパラメータを抽出します。中間ステップのいずれかがnil
の場合はnil
を返します。
params = ActionController::Parameters.new(foo: { bar: { baz: 1 } })
params.dig(:foo, :bar, :baz) # => 1
params.dig(:foo, :zot, :xyz) # => nil
params2 = ActionController::Parameters.new(foo: [10, 11, 12])
params2.dig(:foo, 1) # => 11
🔗 each(&block)
each_pair
のエイリアスです。
🔗 each_key(&block)
パラメータ内のキーごとにブロックを1回ずつ呼び出します。ブロックが渡されていない場合は、代わりにenumeratorを返します。
🔗 each_pair(&block)
値に含まれるすべてのハッシュをパラメータに変換し、Hash#each_pair
と同様にペアごとにyieldします。
each
のエイリアスでもあります。
🔗 each_value(&block)
値に含まれるすべてのハッシュをパラメータに変換し、Hash#each_value
と同様に値ごとにyieldします。
🔗 empty?()
パラメータにキーバリューペアが1つも含まれていない場合はtrue
を返します。
🔗 eql?(other)
🔗 except(*keys)
指定のkeys
をフィルタで除外したActionController::Parameters
の新しいインスタンスを返します。
params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
params.except(:a, :b) # => #<ActionController::Parameters {"c"=>3} permitted: false>
params.except(:d) # => #<ActionController::Parameters {"a"=>1, "b"=>2, "c"=>3} permitted: false>
without
というエイリアスもあります。
🔗 exclude?(key)
指定のキーがパラメータ内に存在しない場合にtrue
を返します。
🔗 expect(*filters)
expect
は、パラメータの必須化と許可を同時に行うための方法として推奨されています。permit
とrequire
を順に呼び出す従来の推奨事項よりも安全です(従来の方法はユーザーが500エラーを誘発できてしまう可能性があります)。
expect
は、従来の.require().permit()
によるパターンで発生する可能性のあるいくつかの潜在的な落とし穴を回避するために、型に対して以下のように従来よりも厳格に振る舞います。
# expectで[:text]を指定すると、text:をキーとするハッシュのみ許される
params = ActionController::Parameters.new(comment: { text: "hello" })
params.expect(comment: [:text])
# => #<ActionController::Parameters { text: "hello" } permitted: true>
# expectで[:text]を指定すると、配列を渡したときにエラーになる
params = ActionController::Parameters.new(comment: [{ text: "hello" }, { text: "world" }])
params.expect(comment: [:text])
# => ActionController::ParameterMissing: param is missing or the value is empty or invalid: comment
パラメータで配列を渡すことを許可するには、配列を必ず明示的に定義しなければなりません。expect
でパラメータに配列が渡されることを期待するには、配列に配列を含めた形式である二重配列記法[[ ]]
を使います。
# expectで[[:text]]を指定すると、ハッシュ`{ text: 値 }`を含む配列を渡せるようになる
params = ActionController::Parameters.new(comments: [{ text: "hello" }, { text: "world" }])
params.expect(comments: [[:text]])
# => [#<ActionController::Parameters { "text" => "hello" } permitted: true>,
# #<ActionController::Parameters { "text" => "world" } permitted: true>]
# expectで[[:text]]を指定すると、配列でラップされていないハッシュ`{ text: 値 }`を渡したときにエラーになる
params = ActionController::Parameters.new(comments: { text: "hello" })
params.expect(comments: [[:text]])
# => ActionController::ParameterMissing: param is missing or the value is empty or invalid: comments
expect
は、従来方式で以下のように配列がハッシュに改ざんされることを防止することを目的としています。
params = ActionController::Parameters.new(user: "hack")
# 従来のrequireとpermitではNoMethodErrorエラーになってしまう
params.require(:user).permit(:name, pets: [:name]) # permitに対して正しくない
# => NoMethodError: undefined method `permit' for an instance of String
# ネステッドパラメータで同じことをやると
params = ActionController::Parameters.new(user: { name: "Martin", pets: { name: "hack" } })
user_params = params.require(:user).permit(:name, pets: [:name]) # permitに対して正しくない
# user_params[:pets]は配列のはずがハッシュになってしまった!
expect
は、型に対してより厳密に振る舞うことでこの問題を解決します。
# NoMethodErrorエラーではなくParameterMissingになる
params = ActionController::Parameters.new(user: "hack")
params.expect(user: [ :name, pets: [[:name]] ])
# => ActionController::ParameterMissing: param is missing or the value is empty or invalid: user
# ネステッドパラメータで同じことをやると不正なハッシュが単に削除される
params = ActionController::Parameters.new(user: { name: "Martin", pets: { name: "hack" } })
user_params = params.expect(user: [:name, pets: [[:name]] ])
user_params[:pets] # => nil
上の例で示したように、expect
には:user
キーの他に、.require.permit
パターンと同様にrootキーも指定する必要があります。rootキーを複数渡すことが期待されている場合は、以下のようにそれらのrootキーすべてが必須キーになります。
# rootキーが2つある場合(pieはハッシュを含む配列でなければならない)
params = ActionController::Parameters.new(name: "Martin", pies: [{ type: "dessert", flavor: "pumpkin"}])
name, pies = params.expect(:name, pies: [[:type, :flavor]])
name # => "Martin"
pies # => [#<ActionController::Parameters {"type"=>"dessert", "flavor"=>"pumpkin"} permitted: true>]
expect
に複数のキーを持つハッシュを渡して呼び出すと、expect
は以下のようにパラメータを許可するとともに、ハッシュで指定した順序のキーを必須化してから、許可済みのパラメータの配列を返します。
# rootキーが2つある場合(subjectとobjectはどちらもハッシュでなければならない)
params = ActionController::Parameters.new(subject: { name: "Martin" }, object: { pie: "pumpkin" })
subject, object = params.expect(subject: [:name], object: [:pie])
subject # => #<ActionController::Parameters {"name"=>"Martin"} permitted: true>
object # => #<ActionController::Parameters {"pie"=>"pumpkin"} permitted: true>
expect
は配列とハッシュの区別が厳密になったことに加えて、内部でpermit
を呼び出しているので、同様に振る舞います。
params = ActionController::Parameters.new({
person: {
name: "Francesco",
age: 22,
pets: [{
name: "Purplish",
category: "dogs"
}]
}
})
permitted = params.expect(person: [ :name, { pets: [[:name]] } ])
permitted.permitted? # => true
permitted[:name] # => "Francesco"
permitted[:age] # => nil
permitted[:pets][0][:name] # => "Purplish"
permitted[:pets][0][:category] # => nil
許可されているスカラー値の配列は、以下のように指定できます。
params = ActionController::Parameters.new(tags: ["rails", "parameters"])
# []は任意のスカラー値を持つ配列を許可する
permitted = params.expect(tags: [])
permitted.permitted? # => true
permitted.is_a?(Array) # => true
permitted.size # => 2
🔗 expect!(*filters)
expect
と同様ですが、raiseするのがActionController::ParameterMissing
ではなくActionController::ExpectedParameterMissing
である点が異なります。
expect
はエラー時に400レスポンスをレンダリングしますが、expect!
は処理されない例外(500レスポンス)を発生させます。これは、内部API
の無効なパラメータをデバッグするときに利用します。パラメータの形式が間違っていると、修正の必要なクライアントライブラリのバグが表示されます。
🔗 extract!(*keys)
指定のキーにマッチするキーバリューペアを破壊的に削除してから、削除したキーバリューペアを返します。
params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
params.extract!(:a, :b) # => #<ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
# c: 3以外は削除される
params # => #<ActionController::Parameters {"c"=>3} permitted: false>
🔗 extract_value(key, delimiter: "_")
指定のキーに対応するパラメータ値を配列で返します。delimiter
を指定すると、その区切り文字で区切った値を返します。
params = ActionController::Parameters.new(id: "1_123", tags: "ruby,rails")
params.extract_value(:id) # => ["1", "123"]
params.extract_value(:tags, delimiter: ",") # => ["ruby", "rails"]
params.extract_value(:non_existent_key) # => nil
ただし、指定したkey
の値に空要素が含まれている場合、返される配列にも空文字列が含まれる点にご注意ください。
params = ActionController::Parameters.new(tags: "ruby,rails,,web")
params.extract_value(:tags, delimiter: ",") # => ["ruby", "rails", "", "web"]
🔗 fetch(key, *args)
指定したkey
に対応するパラメータを返します。
key
が見つからない場合は、いくつかのオプションがあります。
- 他の引数がない場合、
ActionController::ParameterMissing
エラーが発生します。 - 第2引数が指定されている場合は、それが返されます。
(可能な場合はActionController::Parameters
のインスタンスに変換されます) - ブロックが指定されている場合は、そのブロックを実行した結果が返されます。
params = ActionController::Parameters.new(person: { name: "Francesco" })
params.fetch(:person) # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
params.fetch(:none) # => ActionController::ParameterMissing: param is missing or the value is empty or invalid: none
params.fetch(:none, {}) # => #<ActionController::Parameters {} permitted: false>
params.fetch(:none, "Francesco") # => "Francesco"
params.fetch(:none) { "Francesco" } # => "Francesco"
🔗 has_key?
include?
のエイリアスです。
🔗 has_value?(value)
指定した値がパラメータ内の何らかのキーに存在する場合はtrue
を返します。
value?
というエイリアスもあります。
🔗 hash()
🔗 include?(key)
指定したキーがパラメータ内のキーに存在する場合はtrue
を返します。
以下のエイリアスもあります。
🔗 inspect()
🔗 keep_if(&block)
select!
のエイリアスです。
🔗 key?
include?
のエイリアスです。
🔗 keys()
パラメータのキーを新しい配列として返します。
🔗 member?
include?
のエイリアスです。
🔗 merge**(other_hash)
other_hash
のすべてのキーを現在のハッシュにマージした新しいActionController::Parameters
インスタンスを返します。
🔗 merge!(other_hash)
other_hash
のすべてのキーを現在のハッシュにマージしたActionController::Parameters
インスタンスを返す破壊的メソッドです。
🔗 permit(*filters)
filters
で指定した属性だけを含む新しいActionController::Parameters
インスタンスを返し、オブジェクトのpermitted
属性をtrue
に設定します。これは、マスアップデートを許可する危険な属性を制限するのに有用です。
params = ActionController::Parameters.new(name: "Francesco", age: 22, role: "admin")
permitted = params.permit(:name, :age)
permitted.permitted? # => true
permitted.has_key?(:name) # => true
permitted.has_key?(:age) # => true
permitted.has_key?(:role) # => false
許可されているスカラー値だけがフィルタを通過できます。
たとえば以下を指定したとします。
params.permit(:name)
この:name
は、params
のキーが以下のいずれかの型に関連付けられている場合、フィルタをパスします。それ以外のスカラー値であれば、:name
はフィルタで除外されます。
String
Symbol
NilClass
Numeric
TrueClass
FalseClass
Date
Time
DateTime
StringIO
IO
,ActionDispatch::Http::UploadedFile
Rack::Test::UploadedFile
permit
で空の配列[]
を指定すると、そのパラメータは「許可済みのスカラー値を要素に持つ配列」でなければならないことを宣言できます。
params = ActionController::Parameters.new(tags: ["rails", "parameters"])
params.permit(tags: [])
ハッシュパラメータ内の有効なキーやさらに内部の構造を詳しく宣言することが不可能な場合や難しい場合があります。その場合は、以下のように空のハッシュ{}
に対応付けることになります。
params.permit(preferences: {})
ただし空ハッシュ{}
を指定すると任意の入力をユーザーに許してしまうことになるので、十分気をつけなければなりません。この場合のpermit
は、返される構造の値が「許可済みのスカラー値」であることを保証し、それ以外の値をフィルタで除外します。
permit
は、以下のようにネステッドパラメータでも利用できます。
params = ActionController::Parameters.new({
person: {
name: "Francesco",
age: 22,
pets: [{
name: "Purplish",
category: "dogs"
}]
}
})
permitted = params.permit(person: [ :name, { pets: :name } ])
permitted.permitted? # => true
permitted[:person][:name] # => "Francesco"
permitted[:person][:age] # => nil
permitted[:person][:pets][0][:name] # => "Purplish"
permitted[:person][:pets][0][:category] # => nil
この場合、ユーザーが入力を改ざんして、ハッシュが期待されているパラメータにユーザーが文字列を送りつけても拒否できるというメリットも得られます。
permit
に続けてrequire
も指定すると、Railsのフォームの一般的なパターンに従って、パラメータのフィルタリングと必須化を行えます。Rails 8の新しいexpect
メソッドは、このユースケース専用に作成されたもので、パラメータの必須化と許可を行う場合の推奨される方法です。
permitted = params.expect(person: [:name, :age])
permit
とrequire
に分かれている従来の方法を使う場合は、permit
とrequire
の呼び出し順序によって結果が異なる点にご注意ください。
# permitを先に、requireを後で呼ぶ場合
params = ActionController::Parameters.new(person: { name: "Martin", age: 40, role: "admin" })
permitted = params.permit(person: [:name, :age]).require(:person) # 正しい
require
を先に呼び出すと、たとえばユーザーが以下のように:person
に不正な文字列を送りつけるだけで(ParameterMissing
ではなく)NoMethodError
による500エラーを意図的に発生させることが可能になってしまいます。
# requireを先に、permitを後で呼ぶ場合
params = ActionController::Parameters.new(person: "tampered")
permitted = params.require(:person).permit(:name, :age) # 非推奨
#=> NoMethodError: undefined method `permit' for an instance of String
訳注
Rails 7.2までのstrong parametersでは、params.require(:person).permit(:name, :age)
という順序で呼び出すのが通例で、scaffoldで生成したコントローラでもこの順序で呼び出すようになっていました。
Rails 8.0からは基本的にexpect
を使う書き方に改められ、scaffoldで生成したコントローラでもexpect
が使われるようになりました。
ただし、permit
を以下のようにハッシュを指定するキーに対して使う場合、すべてのハッシュが無条件に許可されるとは限らない点にご注意ください。この場合、ハッシュ内のどの属性を許可するかを明示的に指定する必要もあります。
params = ActionController::Parameters.new({
person: {
contact: {
email: "none@test.com",
phone: "555-1234"
}
}
})
# (以下の3つの例は、いずれもpermit、requireの順で呼び出す場合)
# NG: contactハッシュの内容を指定しない書き方はエラーになる
params.permit(person: :contact).require(:person)
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: person
# OK: contactハッシュの内容を{ contact: :phone }で指定している
params.permit(person: { contact: :phone }).require(:person)
# => #<ActionController::Parameters {"contact"=>#<ActionController::Parameters {"phone"=>"555-1234"} permitted: true>} permitted: true>
# OK: contactハッシュの内容を{ contact: [ :email, :phone ] }で指定している
params.permit(person: { contact: [ :email, :phone ] }).require(:person)
# => #<ActionController::Parameters {"contact"=>#<ActionController::Parameters {"email"=>"none@test.com", "phone"=>"555-1234"} permitted: true>} permitted: true>
パラメータで数値を添え字にしたパラメータを複数指定する場合、単一の項目を許可するのと同じ構文を用いて、数値キーの下にある各パラメータ セットを同じにできます。
params = ActionController::Parameters.new({
person: {
'0': {
email: "none@test.com",
phone: "555-1234"
},
'1': {
email: "nothing@test.com",
phone: "555-6789"
},
}
})
params.permit(person: [:email]).to_h
#=> {"person"=>{"0"=>{"email"=>"none@test.com"}, "1"=>{"email"=>"nothing@test.com"}}}
数字キーごとにどのキーが必要かを指定したい場合は、以下のように数字キーごとに個別に指定できます。
params = ActionController::Parameters.new({
person: {
'0': {
email: "none@test.com",
phone: "555-1234"
},
'1': {
email: "nothing@test.com",
phone: "555-6789"
},
}
})
params.permit(person: { '0': [:email], '1': [:phone]}).to_h
# => {"person"=>{"0"=>{"email"=>"none@test.com"}, "1"=>{"phone"=>"555-6789"}}}
🔗 permit!()
permitted
属性をtrue
に設定し、self
を返します。これはマスアサインメントを強制的にパスさせるのに利用できます。
class Person < ActiveRecord::Base
end
params = ActionController::Parameters.new(name: "Francesco")
params.permitted? # => false
Person.new(params) # => ActiveModel::ForbiddenAttributesError
params.permit!
params.permitted? # => true
Person.new(params) # => #<Person id: nil, name: "Francesco">
🔗 permitted?()
パラメータが許可済みの場合はtrue
を、そうでない場合はfalse
を返します。
params = ActionController::Parameters.new
params.permitted? # => false
params.permit!
params.permitted? # => true
🔗 reject(&block)
ブロックがtrue
と評価した項目を削除した新しいActionController::Parameters
インスタンスを返します。
🔗 reject!(&block)
ブロックがtrue
と評価した項目を破壊的に削除し、self
を返します。
delete_if
のエイリアスでもあります。
🔗 require(key)
このメソッドには「単一のキー」も「キーの配列」も渡せます。
単一のキーを渡した場合は、そのキーが存在し、かつそれに関連付けられる値が存在するかシングルトンのfalse
の場合は、渡したキーで指定された値を返します。
ActionController::Parameters.new(person: { name: "Francesco" }).require(:person)
# => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
それ以外の場合は、ActionController::ParameterMissing
をraiseします。
# personが存在しない場合
ActionController::Parameters.new.require(:person)
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: person
# personの値がnilの場合
ActionController::Parameters.new(person: nil).require(:person)
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: person
# personの値が空白文字(ここではTab)の場合
ActionController::Parameters.new(person: "\t").require(:person)
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: person
# personの値が空のハッシュ{}の場合
ActionController::Parameters.new(person: {}).require(:person)
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: person
キーの配列を渡した場合は、各キーの必須化を順に試みます。すべてのキーの必須化に成功すると、個別のキーの戻り値を含む配列が返されます。
params = ActionController::Parameters.new(user: { ... }, profile: { ... })
user_params, profile_params = params.require([:user, :profile])
それ以外の場合、最初に見つかった例外を再度raiseします。
params = ActionController::Parameters.new(user: {}, profile: {})
user_params, profile_params = params.require([:user, :profile])
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: user
require
メソッドは値を許可する処理を行わないため、最終的な値をrequire
メソッドだけで取り出すことは推奨されません。たとえば、以下のようなrequire
メソッドの使い方は問題になる可能性があります。
# 要注意!
params = ActionController::Parameters.new(person: { name: "Finn" })
name = params.require(:person).require(:name) # 要注意!
上の書き方ではなく、以下のようにexpect
を併用することが推奨されます。
def person_params
params.expect(person: :name).require(:name)
end
required
というエイリアスもあります。
🔗 required(key)
require
のエイリアスです。
🔗 reverse_merge(other_hash)
現在のハッシュのすべてのキーを other_hash
にマージした新しいActionController::Parameters
インスタンスを返します。
with_defaults
というエイリアスもあります。
🔗 reverse_merge!(other_hash)
現在のハッシュをother_hash
に破壊的にマージして現在のActionController::Parameters
インスタンスを返します。
with_defaults!
というエイリアスもあります。
🔗 select(&block)
ブロックがtrue
と評価した項目のみを含む新しいActionController::Parameters
インスタンスを返します。
🔗 select!(&block)
RubyのHash#keep_if
と同等の破壊的メソッドですが、変更がなかった場合はnil
を返します。
keep_if
というエイリアスもあります。
🔗 slice(*keys)
指定されたkeys
のみを含む新しいActionController::Parameters
インスタンスを返します。指定されたkeys
が存在しない場合は、空のハッシュを返します。
params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
params.slice(:a, :b) # => #<ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
params.slice(:d) # => #<ActionController::Parameters {} permitted: false>
🔗 slice!(*keys)
指定されたkeys
のみを含んだ現在のActionController::Parameters
インスタンスを返す破壊的メソッドです。
🔗 to_h(&block)
安全なパラメータから、許可されていないキーをすべて削除したActiveSupport::HashWithIndifferentAccess
表現を返します。
params = ActionController::Parameters.new({
name: "Senjougahara Hitagi",
oddity: "Heavy stone crab"
})
# 安全でないパラメータはto_hできない
params.to_h
# => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
# 安全なパラメータはto_hできる
safe_params = params.permit(:name)
safe_params.to_h # => {"name"=>"Senjougahara Hitagi"}
🔗 to_hash()
安全なパラメータから許可されていないキーをすべて削除したHash
表現を返します。
params = ActionController::Parameters.new({
name: "Senjougahara Hitagi",
oddity: "Heavy stone crab"
})
# 安全でないパラメータはto_hashできない
params.to_hash
# => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
# 安全なパラメータはto_hashできる
safe_params = params.permit(:name)
safe_params.to_hash # => {"name"=>"Senjougahara Hitagi"}
🔗 to_param(*args)
to_queryのエイリアスです。
🔗 to_query(*args)
安全なレシーバーを、URLクエリ文字列としての利用に適した文字列表現に変換して返します。
params = ActionController::Parameters.new({
name: "David",
nationality: "Danish"
})
# 安全でないパラメータはto_queryできない
params.to_query
# => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
# 安全なパラメータはto_queryできる
safe_params = params.permit(:name, :nationality)
safe_params.to_query
# => "name=David&nationality=Danish"
オプションの名前空間を渡してキー名を囲むことも可能です。
params = ActionController::Parameters.new({
name: "David",
nationality: "Danish"
})
safe_params = params.permit(:name, :nationality)
# "user[name]=David&user[nationality]=Danish"と同等
safe_params.to_query("user")
# => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
クエリ文字列に適合する文字列ペア"key=value"
は、辞書式に昇順でソートされます。
to_param
のエイリアスでもあります。
🔗 to_s()
パラメータの内容を文字列として返します。
🔗 to_unsafe_h()
安全でなく、フィルタもされていないパラメータのActiveSupport::HashWithIndifferentAccess
表現を返します。
params = ActionController::Parameters.new({
name: "Senjougahara Hitagi",
oddity: "Heavy stone crab"
})
# 安全でないパラメータでもto_unsafe_hできる
params.to_unsafe_h
# => {"name"=>"Senjougahara Hitagi", "oddity" => "Heavy stone crab"}
to_unsafe_hash
のエイリアスでもあります。
🔗 to_unsafe_hash()
to_unsafe_h
のエイリアスです。
🔗 transform_keys(&block)
すべてのキーに対してblock
を1 回ずつ実行した結果を含む新しいActionController::Parameters
インスタンスを返します。値は変更されません。
🔗 transform_keys!(&block)
すべてのキーに対してblock
を1回ずつ実行して改変されたActionController::Parameters
インスタンスを返す破壊的メソッドです。
🔗 transform_values()
すべての値に対してblock
を1回ずつ実行した結果を含む新しいActionController::Parameters
インスタンスを返します。キーは変更されません。
params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
params.transform_values { |x| x * 2 }
# => #<ActionController::Parameters {"a"=>2, "b"=>4, "c"=>6} permitted: false>
🔗 transform_values!()
すべての値に対してblock
を1回ずつ実行して改変されたActionController::Parameters
インスタンスを返す破壊的メソッドです。
🔗 value?(value)
has_value?
のエイリアスです。
🔗 values()
パラメータの値を新しい配列にして返します。
🔗 values_at(*keys)
指定のkeys
に割り当てられている値を配列で返します。Hash
オブジェクトは常にActionController::Parameters
に変換されることにご注意ください。
🔗 with_defaults(other_hash)
reverse_merge
のエイリアスです。
🔗 with_defaults!(other_hash)
reverse_merge!
のエイリアスです。
🔗 without(*keys)
except
のエイリアスです。
🔗 インスタンスprotectedメソッド
🔗 each_nested_attribute()
🔗 nested_attributes?()
🔗 permit_filters(filters, on_unpermitted: nil, explicit_arrays: true)
self
をフィルタリングし、許可されていないキーをオプションでチェックします。
概要
MITライセンスに基づいて翻訳・公開いたします。
ActionController::Parameters
以下と合わせて読むことをおすすめします。