🖥

#Rails permit nested params ( Action Controller Parameters ) example

2020/03/22に公開
# Rails like Nested params with ActionController::Parameters instance
params = ActionController::Parameters.new(
  name: 'Alice',
  age: 22,
  contact: ActionController::Parameters.new(
    tel: 07011112222,
    email: 'user@example.com'
  )
)
# <ActionController::Parameters {"name"=>"Alice", "age"=>22, "contact"=><ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: false>} permitted: false>


# Permit only flat params
permitted_params = params.permit(:name, :age)

# params not changed
# see "permitted: false"
params
# => <ActionController::Parameters {"name"=>"Alice", "age"=>22, "contact"=><ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: false>} permitted: false>

# permit return value is permitted only flat params
permitted_params
# => <ActionController::Parameters {"name"=>"Alice", "age"=>22} permitted: true>


# permit all params
params.permit!

# permitted include all nested params
# see flags "permitted: true"
params
# => <ActionController::Parameters {"name"=>"Alice", "age"=>22, "contact"=><ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: true>} permitted: true>

params.permitted?
# => true

params[:contact].permitted?
# => true



# permit only nested params

params2 = ActionController::Parameters.new(
  name: 'Alice',
  age: 22,
  contact: ActionController::Parameters.new(
    tel: 07011112222,
    email: 'user@example.com'
  )
)


contact_permitted_params = params2[:contact].permit(:tel, :email)
# => <ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: true>

partly_permitted_params2 = params2.merge(contact: contact_permitted_params)
# <ActionController::Parameters {"name"=>"Alice", "age"=>22, "contact"=><ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: true>} permitted: false>

partly_permitted_params2.permitted?
# => false

partly_permitted_params2[:contact].permitted?
# => true

# NOTE
# permit! bang does not receive arguments oh no ...

# params2[:contact].permit!(:tel, :email)
# ArgumentError: wrong number of arguments (given 2, expected 0)

# In this way wee need permit nested params with two times execute methods
#
# 1. permit with args 
# 2. permit!

# params2[:contact].permit(:tel, :email)
# => <ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: true>
# params2[:contact].permit!
# => <ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: true>
# params2
# => <ActionController::Parameters {"name"=>"Alice", "age"=>22, "contact"=><ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: true>} permitted: false>



params_include_nil = ActionController::Parameters.new( name: 'Alice', age: 22, contact: nil )
# => <ActionController::Parameters {"name"=>"Alice", "age"=>22, "contact"=>nil} permitted: false>

# flat permit allowed
params_include_nil.permit(:name, :age, :contact)
# => <ActionController::Parameters {"name"=>"Alice", "age"=>22, "contact"=>nil} permitted: true>

# nexted permit ignored
params_include_nil.permit(:name, :age, contact: [:tel, :email])
# => <ActionController::Parameters {"name"=>"Alice", "age"=>22} permitted: true>



# When nested params has empty values instance
params_include_empty = ActionController::Parameters.new( name: 'Alice', age: 22, contact: ActionController::Parameters.new )
# => <ActionController::Parameters {"name"=>"Alice", "age"=>22, "contact"=><ActionController::Parameters {} permitted: false>} permitted: false>

# NG : When specified as flatten key
#      nested params deleted
params_include_empty.permit(:name, :age, :contact)
# => <ActionController::Parameters {"name"=>"Alice", "age"=>22} permitted: true>

# NG : When specified Empty hash
#      nested params deleted
params_include_empty.permit(:name, :age, contact: [])
# => <ActionController::Parameters {"name"=>"Alice", "age"=>22} permitted: true>

# NG : When specified some key
#      Nothing in permitted nested params but not deleted
params_include_empty.permit(:name, :age, contact: [:tel])
# => <ActionController::Parameters {"name"=>"Alice", "age"=>22, "contact"=><ActionController::Parameters {} permitted: true>} permitted: true>


Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3043

チャットメンバー募集

何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ

Twitter

https://twitter.com/YumaInaura

公開日時

2020-03-22

Discussion