跳至內容 跳至搜尋

動作控制器 Parameters

允許您選擇哪些屬性應該被允許進行批量更新,從而防止意外地暴露不應該暴露的內容。

提供過濾和要求參數的方法

  • expect 可以一步到位地安全地允許和要求參數。

  • permit 用於過濾用於批量賦值的參數。

  • require 用於要求參數或引發錯誤。

範例

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 提供兩個選項來控制新實例的頂層行為

  • permit_all_parameters - 如果它是 true,則默認允許所有參數。默認值是 false

  • action_on_unpermitted_parameters - 控制當發現未明確允許的參數時的行為。默認值在測試和開發環境中是 :log,否則為 false。值可以是

    • false 表示不採取任何行動。

    • :log 表示在 unpermitted_parameters.action_controller 主題上發出 ActiveSupport::Notifications.instrument 事件,並在 DEBUG 級別記錄。

    • :raise 表示引發 ActionController::UnpermittedParameters 異常。

範例

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

請注意,這些選項*不是線程安全的*。在多線程環境中,它們應該只在啟動時設置一次,並且永遠不要在運行時更改。

您可以使用 :key"key" 來獲取 ActionController::Parameters 的值。

params = ActionController::Parameters.new(key: "value")
params[:key]  # => "value"
params["key"] # => "value"
方法
#
A
C
D
E
F
H
I
K
M
N
P
R
S
T
V
W

常數

PERMITTED_SCALAR_TYPES = [ String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, # DateTimes 是 Dates,我們記錄類型但避免冗餘檢查。 StringIO, IO, ActionDispatch::Http::UploadedFile, Rack::Test::UploadedFile, ]
 

— 過濾 ———————————————————-

這是一個允許的純量類型列表,其中包含 XML 和 JSON 請求中支持的類型。

此列表尤其用於過濾普通請求,String 作為第一個元素以快速處理常見情況。

如果您修改此集合,請同時更新 permit 文件中的集合。

屬性

[R] parameters(參數)
[W] permitted(已允許)

類別公開方法

new(parameters = {}, logging_context = {})

返回一個新的 ActionController::Parameters 實例。同時,將 permitted 屬性設置為 ActionController::Parameters.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">
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 287
def initialize(parameters = {}, logging_context = {})
  parameters.each_key do |key|
    unless key.is_a?(String) || key.is_a?(Symbol)
      raise InvalidParameterKey, "all keys must be Strings or Symbols, got: #{key.class}"
    end
  end

  @parameters = parameters.with_indifferent_access
  @logging_context = logging_context
  @permitted = self.class.permit_all_parameters
end

實例公開方法

==(other)

如果另一個 Parameters 對象包含相同的內容和允許標誌,則返回 true。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 301
def ==(other)
  if other.respond_to?(:permitted?)
    permitted? == other.permitted? && parameters == other.parameters
  else
    super
  end
end

[](key)

返回給定 key 的參數。如果找不到,則返回 nil

params = ActionController::Parameters.new(person: { name: "Francesco" })
params[:person] # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
params[:none]   # => nil
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 797
def [](key)
  convert_hashes_to_parameters(key, @parameters[key])
end

[]=(key, value)

將值賦給給定的 key。當調用 permit 時,給定的鍵仍然可能被過濾掉。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 803
def []=(key, value)
  @parameters[key] = value
end

as_json(options=nil)

返回一個雜湊,可用作參數的 JSON 表示形式。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 194
    

compact()

返回一個已移除 nil 值的新 ActionController::Parameters 實例。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 974
def compact
  new_instance_with_inherited_permitted_status(@parameters.compact)
end

compact!()

移除所有 nil 值,並返回 self;如果沒有任何更改,則返回 nil

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 980
def compact!
  self if @parameters.compact!
end

compact_blank()

傳回一個沒有空白值的新 `ActionController::Parameters` 實例。使用 `Object#blank?` 來判斷值是否為空白。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 986
def compact_blank
  reject { |_k, v| v.blank? }
end

compact_blank!()

移除所有空白值並返回自身。使用 Object#blank? 來判斷值是否為空白。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 992
def compact_blank!
  reject! { |_k, v| v.blank? }
end

converted_arrays()

追蹤已轉換陣列(如果有的話)的屬性,以避免在常見用例 permit + 批量賦值中重複循環。在方法中定義,以便僅在需要時才實例化它。

測試成員資格仍然會循環,但它比我們自己轉換值的循環更快。此外,我們不會為每次提取構建新的陣列對象。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 435
def converted_arrays
  @converted_arrays ||= Set.new
end

deep_dup()

返回具有相同允許參數的重複 ActionController::Parameters 實例。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1092
def deep_dup
  self.class.new(@parameters.deep_dup, @logging_context).tap do |duplicate|
    duplicate.permitted = @permitted
  end
end

deep_merge(other_hash, &block)

返回一個新的 `ActionController::Parameters` 實例,其中 `self` 和 `other_hash` 以遞迴方式合併。

與標準庫中的 `Hash#merge` 一樣,可以提供一個區塊來合併值。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 168
    

deep_merge!(other_hash, &block)

#deep_merge 相同,但修改 self

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 183
    

deep_transform_keys(&block)

返回一個新的 `ActionController::Parameters` 實例,其中包含對每個鍵運行一次 `block` 的結果。這包括來自根雜湊以及所有嵌套雜湊和陣列的鍵。值保持不變。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 924
def deep_transform_keys(&block)
  new_instance_with_inherited_permitted_status(
    _deep_transform_keys_in_object(@parameters, &block).to_unsafe_h
  )
end

deep_transform_keys!(&block)

返回具有已更改鍵的相同 `ActionController::Parameters` 實例。這包括來自根雜湊以及所有嵌套雜湊和陣列的鍵。值保持不變。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 933
def deep_transform_keys!(&block)
  @parameters = _deep_transform_keys_in_object(@parameters, &block).to_unsafe_h
  self
end

delete(key, &block)

從 `Parameters` 中刪除鍵值對並返回該值。如果找不到 `key`,則返回 `nil`(或者,使用可選程式碼區塊,產生 `key` 並返回結果)。此方法類似於 `extract!`,後者返回相應的 `ActionController::Parameters` 對象。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 942
def delete(key, &block)
  convert_value_to_parameters(@parameters.delete(key, &block))
end

delete_if(&block)

別名:reject!

dig(*keys)

透過在每個步驟呼叫 `dig` 方法,從給定的 `keys` 中提取巢狀參數。如果任何中間步驟為 `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
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 841
def dig(*keys)
  convert_hashes_to_parameters(keys.first, @parameters[keys.first])
  @parameters.dig(*keys)
end

each(&block)

`each_pair` 的別名

each_key(&block)

針對參數中的每個鍵呼叫一次區塊,並傳遞該鍵。如果沒有給出區塊,則返回一個列舉器。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 202
    

each_pair(&block)

將值中的所有雜湊轉換為參數,然後以與 `Hash#each_pair` 相同的方式產生每一對鍵值對。

也作為 `each` 的別名
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 402
def each_pair(&block)
  return to_enum(__callee__) unless block_given?
  @parameters.each_pair do |key, value|
    yield [key, convert_hashes_to_parameters(key, value)]
  end

  self
end

each_value(&block)

將值中的所有雜湊轉換為參數,然後以與 `Hash#each_value` 相同的方式產生每個值。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 414
def each_value(&block)
  return to_enum(:each_value) unless block_given?
  @parameters.each_pair do |key, value|
    yield convert_hashes_to_parameters(key, value)
  end

  self
end

empty?()

如果參數沒有鍵值對,則返回 true。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 211
    

eql?(other)

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 309
def eql?(other)
  self.class == other.class &&
    permitted? == other.permitted? &&
    parameters.eql?(other.parameters)
end

except(*keys)

返回一個新的 `ActionController::Parameters` 實例,其中過濾掉了給定的 `keys`。

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` 的別名
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 869
def except(*keys)
  new_instance_with_inherited_permitted_status(@parameters.except(*keys))
end

exclude?(key)

如果參數中不存在給定的鍵,則返回 true。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 219
    

expect(*filters)

`expect` 是要求和允許參數的首選方法。它比先前建議的依序呼叫 `permit` 和 `require` 更安全,後者可能允許使用者觸發 500 錯誤。

`expect` 對類型更嚴格,可以避免使用 `.require.permit` 模式可能遇到的許多潛在陷阱。

例如

params = ActionController::Parameters.new(comment: { text: "hello" })
params.expect(comment: [:text])
# => #<ActionController::Parameters { text: "hello" } permitted: true>

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

為了允許參數陣列,必須明確定義陣列。使用雙重陣列括號(陣列中的陣列)來宣告預期參數陣列。

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

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")
# The previous way of requiring and permitting parameters will error
params.require(:user).permit(:name, pets: [:name]) # wrong
# => NoMethodError: undefined method `permit' for an instance of String

# similarly with nested parameters
params = ActionController::Parameters.new(user: { name: "Martin", pets: { name: "hack" } })
user_params = params.require(:user).permit(:name, pets: [:name]) # wrong
# user_params[:pets] is expected to be an array but is a hash

`expect` 通過對類型更嚴格來解決這個問題。

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

# with nested parameters
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` 模式類似的根鍵。如果預期有多個根鍵,則都需要它們。

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` 將允許參數並按照雜湊中給出的順序要求鍵,返回允許參數的陣列。

params = `ActionController::Parameters.new`(subject: { name: “Martin” }, object: { pie: “pumpkin” }) subject, object = params.expect(subject: [:name], object: [:pie]) subject # =>

除了對陣列與雜湊參數更嚴格之外,`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
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 772
def expect(*filters)
  params = permit_filters(filters)
  keys = filters.flatten.flat_map { |f| f.is_a?(Hash) ? f.keys : f }
  values = params.require(keys)
  values.size == 1 ? values.first : values
end

expect!(*filters)

與 `expect` 相同,但引發 `ActionController::ExpectedParameterMissing` 而不是 `ActionController::ParameterMissing`。與將呈現 400 回應的 `expect` 不同,`expect!` 將引發未處理的例外。這旨在偵錯內部 `API` 的無效參數,其中格式錯誤的參數表示用戶端程式庫中應修復的錯誤。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 786
def expect!(*filters)
  expect(*filters)
rescue ParameterMissing => e
  raise ExpectedParameterMissing.new(e.param, e.keys)
end

extract!(*keys)

移除並返回與給定鍵匹配的鍵值對。

params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
params.extract!(:a, :b) # => #<ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
params                  # => #<ActionController::Parameters {"c"=>3} permitted: false>
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 879
def extract!(*keys)
  new_instance_with_inherited_permitted_status(@parameters.extract!(*keys))
end

extract_value(key, delimiter: "_")

返回以 `delimiter` 分隔的給定 `key` 的參數值

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"]
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1110
def extract_value(key, delimiter: "_")
  @parameters[key]&.split(delimiter, -1)
end

fetch(key, *args)

返回給定 `key` 的參數。如果找不到 `key`,則有以下選項:沒有其他參數,它將引發 `ActionController::ParameterMissing` 錯誤;如果給出第二個參數,則返回該參數(如果可能,將其轉換為 `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"
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 820
def fetch(key, *args)
  convert_value_to_parameters(
    @parameters.fetch(key) {
      if block_given?
        yield
      else
        args.fetch(0) { raise ActionController::ParameterMissing.new(key, @parameters.keys) }
      end
    }
  )
end

has_key?

`include?` 的別名

has_value?(value)

如果參數中存在給定值的鍵,則返回 true。

也作為 `value?` 的別名
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 997
def has_value?(value)
  each_value.include?(convert_value_to_parameters(value))
end

hash()

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 315
def hash
  [self.class, @parameters, @permitted].hash
end

include?(key)

如果參數中存在給定的鍵,則返回 true。

也作為 `has_key?`、`key?`、`member?` 的別名
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 227
    

inspect()

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1055
def inspect
  "#<#{self.class} #{@parameters} permitted: #{@permitted}>"
end

keep_if(&block)

`select!` 的別名

key?

`include?` 的別名

keys()

返回一個包含參數所有鍵的新陣列。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 235
    

member?

`include?` 的別名

merge(other_hash)

返回一個新的 `ActionController::Parameters` 實例,其中 `other_hash` 的所有鍵都合併到目前的雜湊中。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1011
def merge(other_hash)
  new_instance_with_inherited_permitted_status(
    @parameters.merge(other_hash.to_h)
  )
end

merge!(other_hash)

返回目前的 `ActionController::Parameters` 實例,其中 `other_hash` 合併到目前的雜湊中。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1022
def merge!(other_hash, &block)
  @parameters.merge!(other_hash.to_h, &block)
  self
end

permit(*filters)

返回一個新的 ActionController::Parameters 實例,其中僅包含給定的 filters 並將物件的 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)

如果 :nameparams 的鍵,其關聯值類型為 StringSymbolNilClassNumericTrueClassFalseClassDateTimeDateTimeStringIOIOActionDispatch::Http::UploadedFileRack::Test::UploadedFile,則 :name 將通過。否則,鍵 :name 將被過濾掉。

您可以通過將參數映射到一個空陣列來聲明該參數應為允許的純量值的陣列

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

這還有一個額外的好處,就是可以拒絕使用者修改的輸入,這些輸入在預期為雜湊時發送字串。

後接 require 時,您可以按照典型的 Rails 表單模式來過濾和要求參數。expect 方法專為這種用例而設計,是要求和允許參數的推薦方法。

 permitted = params.expect(person: [:name, :age])

當單獨使用 permitrequire 時,請仔細注意方法調用的順序。

 params = ActionController::Parameters.new(person: { name: "Martin", age: 40, role: "admin" })
 permitted = params.permit(person: [:name, :age]).require(:person) # correct

當先使用 require 時,您的應用程式使用者可能會在使用者例如為 :person 發送字串時觸發 NoMethodError。

 params = ActionController::Parameters.new(person: "tampered")
 permitted = params.require(:person).permit(:name, :age) # not recommended
 # => NoMethodError: undefined method `permit' for an instance of String

請注意,如果您在指向雜湊的鍵中使用 permit,它不會允許整個雜湊。您還需要指定雜湊內應允許哪些屬性。

params = ActionController::Parameters.new({
  person: {
    contact: {
      email: "none@test.com",
      phone: "555-1234"
    }
  }
})

params.permit(person: :contact).require(:person)
# => #<ActionController::Parameters {} permitted: true>

params.permit(person: { contact: :phone }).require(:person)
# => #<ActionController::Parameters {"contact"=>#<ActionController::Parameters {"phone"=>"555-1234"} permitted: true>} permitted: true>

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"}}}
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 668
def permit(*filters)
  permit_filters(filters, on_unpermitted: self.class.action_on_unpermitted_parameters, explicit_arrays: false)
end

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">
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 461
def permit!
  each_pair do |key, value|
    Array.wrap(value).flatten.each do |v|
      v.permit! if v.respond_to? :permit!
    end
  end

  @permitted = true
  self
end

permitted?()

如果參數被允許,則返回 true,否則返回 false

params = ActionController::Parameters.new
params.permitted? # => false
params.permit!
params.permitted? # => true
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 445
def permitted?
  @permitted
end

reject(&block)

返回一個新的 `ActionController::Parameters` 實例,其中區塊評估為 true 的項目已被移除。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 961
def reject(&block)
  new_instance_with_inherited_permitted_status(@parameters.reject(&block))
end

reject!(&block)

移除區塊評估為 true 的項目並返回自身。

也稱為:delete_if
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 966
def reject!(&block)
  @parameters.reject!(&block)
  self
end

require(key)

此方法接受單個鍵和鍵陣列。

當傳遞單個鍵時,如果它存在且其關聯值存在或單例 `false`,則返回該值

ActionController::Parameters.new(person: { name: "Francesco" }).require(:person)
# => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>

否則引發 `ActionController::ParameterMissing`

ActionController::Parameters.new.require(:person)
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: person

ActionController::Parameters.new(person: nil).require(:person)
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: person

ActionController::Parameters.new(person: "\t").require(:person)
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: 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])

否則,該方法會重新引發找到的第一個異常

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

不建議使用此方法來擷取終端值,因為它不允許這些值。例如,這可能會導致問題

# CAREFUL
params = ActionController::Parameters.new(person: { name: "Finn" })
name = params.require(:person).require(:name) # CAREFUL

建議改用 `expect`

def person_params
  # params.expect(person: :name).require(:name)
end
也稱為:required
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 519
def require(key)
  return key.map { |k| require(k) } if key.is_a?(Array)
  value = self[key]
  if value.present? || value == false
    value
  else
    raise ParameterMissing.new(key, @parameters.keys)
  end
end

required(key)

別名:require

reverse_merge(other_hash)

返回一個新的 `ActionController::Parameters` 實例,其中目前雜湊中的所有鍵都合併到 `other_hash` 中。

也稱為:with_defaults
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1033
def reverse_merge(other_hash)
  new_instance_with_inherited_permitted_status(
    other_hash.to_h.merge(@parameters)
  )
end

reverse_merge!(other_hash)

返回目前的 `ActionController::Parameters` 實例,其中目前雜湊已合併到 `other_hash` 中。

也稱為:with_defaults!
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1042
def reverse_merge!(other_hash)
  @parameters.merge!(other_hash.to_h) { |key, left, right| left }
  self
end

select(&block)

返回一個新的 `ActionController::Parameters` 實例,其中僅包含區塊評估為 true 的項目。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 948
def select(&block)
  new_instance_with_inherited_permitted_status(@parameters.select(&block))
end

select!(&block)

等同於 Hash#keep_if,但如果沒有任何更改,則返回 `nil`。

也稱為:keep_if
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 953
def select!(&block)
  @parameters.select!(&block)
  self
end

slice(*keys)

返回一個新的 `ActionController::Parameters` 實例,其中僅包含給定的 `keys`。如果給定的 `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>
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 852
def slice(*keys)
  new_instance_with_inherited_permitted_status(@parameters.slice(*keys))
end

slice!(*keys)

返回目前的 `ActionController::Parameters` 實例,其中僅包含給定的 `keys`。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 858
def slice!(*keys)
  @parameters.slice!(*keys)
  self
end

to_h(&block)

返回一個安全的 `ActiveSupport::HashWithIndifferentAccess` 參數表示形式,其中所有未經允許的鍵都已移除。

params = ActionController::Parameters.new({
  name: "Senjougahara Hitagi",
  oddity: "Heavy stone crab"
})
params.to_h
# => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash

safe_params = params.permit(:name)
safe_params.to_h # => {"name"=>"Senjougahara Hitagi"}
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 331
def to_h(&block)
  if permitted?
    convert_parameters_to_hashes(@parameters, :to_h, &block)
  else
    raise UnfilteredParameters
  end
end

to_hash()

返回一個安全的 `Hash` 參數表示形式,其中所有未經允許的鍵都已移除。

params = ActionController::Parameters.new({
  name: "Senjougahara Hitagi",
  oddity: "Heavy stone crab"
})
params.to_hash
# => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash

safe_params = params.permit(:name)
safe_params.to_hash # => {"name"=>"Senjougahara Hitagi"}
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 351
def to_hash
  to_h.to_hash
end

to_param(*args)

別名:to_query

to_query(*args)

返回接收器的字串表示形式,適合用作 URL 查詢字串

params = ActionController::Parameters.new({
  name: "David",
  nationality: "Danish"
})
params.to_query
# => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash

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)
safe_params.to_query("user")
# => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"

構成查詢字串的字串對 `“key=value”` 按字典順序升序排序。

也稱為:to_param
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 381
def to_query(*args)
  to_h.to_query(*args)
end

to_s()

將參數的內容作為字串返回。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 250
delegate :keys, :empty?, :exclude?, :include?,
  :as_json, :to_s, :each_key, to: :@parameters

to_unsafe_h()

返回一個不安全的、未經過濾的 `ActiveSupport::HashWithIndifferentAccess` 參數表示形式。

params = ActionController::Parameters.new({
  name: "Senjougahara Hitagi",
  oddity: "Heavy stone crab"
})
params.to_unsafe_h
# => {"name"=>"Senjougahara Hitagi", "oddity" => "Heavy stone crab"}
也稱為:to_unsafe_hash
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 395
def to_unsafe_h
  convert_parameters_to_hashes(@parameters, :to_unsafe_h)
end

to_unsafe_hash()

別名:to_unsafe_h

transform_keys(&block)

返回一個新的 `ActionController::Parameters` 實例,其中包含對每個鍵執行一次 `block` 的結果。值保持不變。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 906
def transform_keys(&block)
  return to_enum(:transform_keys) unless block_given?
  new_instance_with_inherited_permitted_status(
    @parameters.transform_keys(&block)
  )
end

transform_keys!(&block)

執行鍵轉換並返回已更改的 `ActionController::Parameters` 實例。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 915
def transform_keys!(&block)
  return to_enum(:transform_keys!) unless block_given?
  @parameters.transform_keys!(&block)
  self
end

transform_values()

傳回一個新的 ActionController::Parameters 實例,其中包含對每個值執行一次 block 的結果。鍵保持不變。

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>
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 889
def transform_values
  return to_enum(:transform_values) unless block_given?
  new_instance_with_inherited_permitted_status(
    @parameters.transform_values { |v| yield convert_value_to_parameters(v) }
  )
end

transform_values!()

執行值轉換並傳回已更改的 ActionController::Parameters 實例。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 898
def transform_values!
  return to_enum(:transform_values!) unless block_given?
  @parameters.transform_values! { |v| yield convert_value_to_parameters(v) }
  self
end

value?(value)

別名:has_value?

values()

傳回一個包含參數值的新陣列。

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 424
def values
  to_enum(:each_value).to_a
end

values_at(*keys)

傳回指派給指定 keys 的值。請注意,所有 Hash 物件都將轉換為 ActionController::Parameters

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1005
def values_at(*keys)
  convert_value_to_parameters(@parameters.values_at(*keys))
end

with_defaults(other_hash)

別名:reverse_merge

with_defaults!(other_hash)

without(*keys)

別名:except

實例保護方法 (Instance Protected methods)

each_nested_attribute()

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1123
def each_nested_attribute
  hash = self.class.new
  self.each { |k, v| hash[k] = yield v if Parameters.nested_attribute?(k, v) }
  hash
end

nested_attributes?()

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1119
def nested_attributes?
  @parameters.any? { |k, v| Parameters.nested_attribute?(k, v) }
end

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

過濾自身並選擇性地檢查未經允許的鍵

# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1130
def permit_filters(filters, on_unpermitted: nil, explicit_arrays: true)
  params = self.class.new

  filters.flatten.each do |filter|
    case filter
    when Symbol, String
      # Declaration [:name, "age"]
      permitted_scalar_filter(params, filter)
    when Hash
      # Declaration [{ person: ... }]
      hash_filter(params, filter, on_unpermitted:, explicit_arrays:)
    end
  end

  unpermitted_parameters!(params, on_unpermitted:)

  params.permit!
end