このような何か:IRBで
REQUIRED = %i(name).freeze
ALLOWED = (%i(filter query_elements) + REQUIRED).freeze
MAX_DEPTH = 5
def ensure_params(hash, nest_level = 0) # ah I never come up with good names...
raise 'you went too deep man' if nest_level > MAX_DEPTH
hash.fetch_values(*REQUIRED)
hash[:query_elements] = ensure_params(hash[:query_elements], nest_level + 1) if hash[:query_elements]
hash.slice(*ALLOWED)
end
:
> ensure_params({ :filter => 2, :name => 'test', unpermitted_param: :something, :query_elements => { filter: 3, name: 'test', nested_unpermitted: 13 } })
# => {:filter=>2, :query_elements=>{:filter=>3, :name=>"test"}, :name=>"test"}
> ensure_params({ name: 1, query_elements: { notname: 1 } })
KeyError: key not found: :name
> MAX_DEPTH = 3
# => 3
> ensure_params({ name: 1, query_elements: { name: 1, query_elements: { name: 1, query_elements: { name: 1, query_elements: { name: 1, query_elements: { name: 1 } } } } }})
RuntimeError: you went too deep man
シンボルにキーを変換するように行うことができるいくつかの改善は、おそらくあり、あなたを伝えるために、より良いエラーメッセージを持っていますネストレベルに欠けているキーなどがあります。
「はるかに遅い」とはどういう意味ですか? –
これらのオブジェクトは非常に深くネストされる傾向があるので、要求ごとにこれらの大きなツリーをステップ実行することは理想的ではありません。 – user1456632
ホワイトリスト作成はどのように機能すると思いますか?構造を踏み込むことは避けられません。 –