Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Rails 8 API: ActionController::Parameters(翻訳)

概要

MITライセンスに基づいて翻訳・公開いたします。

以下と合わせて読むことをおすすめします。

Rails 8: strong parametersの新しいparams.expectの使い方(翻訳)

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">

GitHub

🔗 インスタンスpublicメソッド

🔗 ==(other)

別のParametersオブジェクトと比較したときに、オブジェクトのコンテンツとpermittedフラグの設定が同じであればtrueを返します。

GitHub

🔗 [](key)

指定のkeyに対応するパラメータを返します。パラメータが見つからない場合はnilを返します。

params = ActionController::Parameters.new(person: { name: "Francesco" })
params[:person] # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
params[:none]   # => nil

GitHub

🔗 []=(key, value)

指定されたkeyに値を代入します。ここで指定したキーは、permitが呼び出されたときに引き続きフィルタで除外される可能性があります。

GitHub

🔗 as_json(options=nil)

パラメータのJSON表現として利用できるハッシュを返します。

GitHub

🔗 compact()

nil値を削除したActionController::Parametersの新しいインスタンスを返します。

GitHub

🔗 compact!()

nil値を削除したselfを返す破壊的メソッドです。変更が発生しなかった場合はnilを返します。

GitHub

🔗 compact_blank()

空白値を含まない新しいActionController::Parametersインスタンスを返します。値が空白かどうかはObject#blank?メソッドで判定されます。

GitHub

🔗 compact_blank!()

空白値をすべて削除したselfを返す破壊的メソッドです。値が空白かどうかはObject#blank?メソッドで判定されます。

GitHub

🔗 converted_arrays()

permitとマスアサインメントの一般的なユースケースで二重ループを書かずに済むよう、変換済み配列をトラッキングする属性です(内部用)。必要な時だけインスタンス化するためにメソッドで定義します。

Testingによるメンバーシップの存在チェックのループが解消されるわけではありませんが、独自のループで値を変換するよりも高速です。また、フェッチのたびに配列オブジェクトを新たにビルドすることがなくなります。

GitHub

🔗 deep_dup()

ActionController::Parametersインスタンスの複製を返します。返されるインスタンスのpermittedパラメータは元と同じ値になります。

GitHub

🔗 deep_merge(other_hash, &block)

selfother_hashを再帰的にマージする形で、ActionController::Parametersの新しいインスタンスを返します。

Ruby標準ライブラリのHash#mergeと同様に、マージの値にはブロックも渡せます。

GitHub

🔗 deep_merge!(other_hash, &block)

 selfを改変すること以外は#deep_mergeと同じです。

GitHub

🔗 deep_transform_keys(&block)

個別のキーに対してblockを1回ずつ実行した結果を含む、ActionController::Parametersの新しいインスタンスを返します。これにはrootハッシュのキーも、ネストしたハッシュや配列のキーもすべて含まれます。値は変更されません。

GitHub

🔗 deep_transform_keys!(&block)

キーを破壊的に変更したActionController::Parametersの同じインスタンスを返します。これにはrootハッシュのキーも、ネストしたハッシュや配列のキーもすべて含まれます。値は変更されません。

GitHub

🔗 delete(key, &block)

Parametersからキーバリューペアを1個削除してから、削除した値を返します。keyが見つからない場合はnilを返します(オプションのコードブロックを渡した場合は、key を生成して結果を返します)。このメソッドは、対応するActionController::Parametersオブジェクトを返す extract!に似ています。

GitHub

🔗 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

GitHub

🔗 each(&block)

each_pairのエイリアスです。

🔗 each_key(&block)

パラメータ内のキーごとにブロックを1回ずつ呼び出します。ブロックが渡されていない場合は、代わりにenumeratorを返します。

GitHub

🔗 each_pair(&block)

値に含まれるすべてのハッシュをパラメータに変換し、Hash#each_pairと同様にペアごとにyieldします。

eachのエイリアスでもあります。

GitHub

🔗 each_value(&block)

値に含まれるすべてのハッシュをパラメータに変換し、Hash#each_valueと同様に値ごとにyieldします。

GitHub

🔗 empty?()

パラメータにキーバリューペアが1つも含まれていない場合はtrueを返します。

GitHub

🔗 eql?(other)

GitHub

🔗 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というエイリアスもあります。

GitHub

🔗 exclude?(key)

指定のキーがパラメータ内に存在しない場合にtrueを返します。

GitHub

🔗 expect(*filters)

expectは、パラメータの必須化と許可を同時に行うための方法として推奨されています。permitrequireを順に呼び出す従来の推奨事項よりも安全です(従来の方法はユーザーが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

GitHub

🔗 expect!(*filters)

expectと同様ですが、raiseするのがActionController::ParameterMissingではなくActionController::ExpectedParameterMissingである点が異なります。

expectはエラー時に400レスポンスをレンダリングしますが、expect!は処理されない例外(500レスポンス)を発生させます。これは、内部APIの無効なパラメータをデバッグするときに利用します。パラメータの形式が間違っていると、修正の必要なクライアントライブラリのバグが表示されます。

GitHub

🔗 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>

GitHub

🔗 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"]

GitHub

🔗 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"

GitHub

🔗 has_key?

include?のエイリアスです。

🔗 has_value?(value)

指定した値がパラメータ内の何らかのキーに存在する場合はtrueを返します。

value?というエイリアスもあります。

GitHub

🔗 hash()

GitHub

🔗 include?(key)

指定したキーがパラメータ内のキーに存在する場合はtrueを返します。

以下のエイリアスもあります。

GitHub

🔗 inspect()

GitHub

🔗 keep_if(&block)

select!のエイリアスです。

🔗 key?

include?のエイリアスです。

🔗 keys()

パラメータのキーを新しい配列として返します。

GitHub

🔗 member?

include?のエイリアスです。

🔗 merge**(other_hash)

other_hashのすべてのキーを現在のハッシュにマージした新しいActionController::Parametersインスタンスを返します。

GitHub

🔗 merge!(other_hash)

other_hashのすべてのキーを現在のハッシュにマージしたActionController::Parametersインスタンスを返す破壊的メソッドです。

GitHub

🔗 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はフィルタで除外されます。

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])

permitrequireに分かれている従来の方法を使う場合は、permitrequireの呼び出し順序によって結果が異なる点にご注意ください。

# 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"}}}

GitHub

🔗 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">

GitHub

🔗 permitted?()

パラメータが許可済みの場合はtrueを、そうでない場合はfalseを返します。

params = ActionController::Parameters.new
params.permitted? # => false
params.permit!
params.permitted? # => true

GitHub

🔗 reject(&block)

ブロックがtrueと評価した項目を削除した新しいActionController::Parametersインスタンスを返します。

GitHub

🔗 reject!(&block)

ブロックがtrueと評価した項目を破壊的に削除し、selfを返します。

delete_ifのエイリアスでもあります。

GitHub

🔗 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というエイリアスもあります。

GitHub

🔗 required(key)

requireのエイリアスです。

🔗 reverse_merge(other_hash)

現在のハッシュのすべてのキーを other_hashにマージした新しいActionController::Parametersインスタンスを返します。

with_defaultsというエイリアスもあります。

GitHub

🔗 reverse_merge!(other_hash)

現在のハッシュをother_hashに破壊的にマージして現在のActionController::Parametersインスタンスを返します。

with_defaults!というエイリアスもあります。

GitHub

🔗 select(&block)

ブロックがtrueと評価した項目のみを含む新しいActionController::Parametersインスタンスを返します。

GitHub

🔗 select!(&block)

RubyのHash#keep_ifと同等の破壊的メソッドですが、変更がなかった場合はnilを返します。

keep_ifというエイリアスもあります。

GitHub

🔗 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>

GitHub

🔗 slice!(*keys)

指定されたkeysのみを含んだ現在のActionController::Parametersインスタンスを返す破壊的メソッドです。

GitHub

🔗 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"}

GitHub

🔗 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"}

GitHub

🔗 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のエイリアスでもあります。

GitHub

🔗 to_s()

パラメータの内容を文字列として返します。

GitHub

🔗 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のエイリアスでもあります。

GitHub

🔗 to_unsafe_hash()

to_unsafe_hのエイリアスです。

🔗 transform_keys(&block)

すべてのキーに対してblockを1 回ずつ実行した結果を含む新しいActionController::Parametersインスタンスを返します。値は変更されません。

GitHub

🔗 transform_keys!(&block)

すべてのキーに対してblockを1回ずつ実行して改変されたActionController::Parametersインスタンスを返す破壊的メソッドです。

GitHub

🔗 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>

GitHub

🔗 transform_values!()

すべての値に対してblockを1回ずつ実行して改変されたActionController::Parametersインスタンスを返す破壊的メソッドです。

GitHub

🔗 value?(value)

has_value?のエイリアスです。

🔗 values()

パラメータの値を新しい配列にして返します。

GitHub

🔗 values_at(*keys)

指定のkeysに割り当てられている値を配列で返します。Hashオブジェクトは常にActionController::Parametersに変換されることにご注意ください。

GitHub

🔗 with_defaults(other_hash)

reverse_mergeのエイリアスです。

🔗 with_defaults!(other_hash)

reverse_merge!のエイリアスです。

🔗 without(*keys)

exceptのエイリアスです。

🔗 インスタンスprotectedメソッド

🔗 each_nested_attribute()

GitHub

🔗 nested_attributes?()

GitHub

🔗 permit_filters(filters, on_unpermitted: nil, explicit_arrays: true)

selfをフィルタリングし、許可されていないキーをオプションでチェックします。

GitHub

関連記事

Rails 8: strong parametersの新しいparams.expectの使い方(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。