#Rails の Controller でネストした params を permit / require するのはメソッドチェーンじゃいかんともしがたいからメソッドを何度も実行するしかないのか？ ( ActionController::Parameters )

- require / permit / permit! の引数の受け取り方も、返り値も使い方もなんだか不揃いで、なんとも使いがたい
- メソッドチェーンも使いづらくパラメータがネストされている時に permit / require しづらい
- permit! は引数を受け取れず、破壊的に params を変えてしまう
- require と permit を別々に実行して、頑張って組み立て直す必要があるかもしれない
- 具体ケースとしては JSON リクエストを受け取った結果を Controller の params で扱っているのだが、Rails のもともとのフレームワークのレールからは外れる部分が多いのか、苦労がある。

```rb
# ネストした params
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>


# require は必須パラメータチェックのためだけに利用して、返り値は使わない
params.require([:name, :age, :contact])
params[:contact].require([:tel, :email])

# permit する時はネストの構造に合わせた書き方をして、返り値を permit された params として利用する
peritted_params = params.permit(:name, :age, contact: [:tel, :email])
# => <ActionController::Parameters {"name"=>"Alice", "age"=>22, "contact"=><ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: true>} permitted: true>
```

僕はもう疲れたよ

![image](https://user-images.githubusercontent.com/13635059/77215222-54114980-6b56-11ea-8510-1d61c450d0dd.png)


# 公式

- tap のブロックで頑張る方法が書かれていた
- 結局 Action Controller Parameters は頼りに出来ない気がした

```rb
def person_params
  params.require(:person).permit(:name).tap do |person_params|
    person_params.require(:name) # SAFER
  end
end
```

[ActionController::Parameters](https://api.rubyonrails.org/classes/ActionController/Parameters.html)

# example

```rb

# Execute with rails console

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

# Ooops
# Args must be Array
params.require(:name, :age, :contact)
# ArgumentError: wrong number of arguments (given 3, expected 1)

# It works
params.require([:name, :age, :contact])
# => ["Alice", 22, <ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: false>]

# But with method chain
# How to permit multiple params Require and Permit ?

# require method returns values Array
# it is not work for generate permitted params
# because .permit .require both method does not change "params"
params.require([:name, :age, :contact])[2].permit(:tel, :email).require([:tel, :email])
# => [941921426, "user@example.com"]

# require method returns values Array
# Unable to use methods chain
params.require([:name, :age, :contact])[2].require([:tel, :email]).permit(:tel, :email)
# NoMethodError: undefined method `permit' for [941921426, "user@example.com"]:Array

# It is answer?
# User require and permit methods
# Without return values
# Without method chains
# 
# And last execute permit!

params.require([:name, :age, :contact])
params[:contact].require([:tel, :email])

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

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

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->