2017-11-15 3 views
1

子クラスQueryGroupを持つモデルQueryElementがあります。 QueryGroupには、ネストされたQueryElementsを含めることができます。その上無限にネスト可能なモデルの強力なパラメータをレンダリングします。

params.fetch(:query).permit(:name, :filter, :query_elements => [:name, :filter, :query_elements => [...] 

そして、私のようなものを持っている強力なパラメータのためにそう

セイQueryGroupは、propertyNameのを持っている、とQueryElementは(単なる例)プロパティフィルターを持つ

私はむしろ避けたいと思う強力なパラメータのセキュリティを破るか、ツリーを手作業で歩くことができますが、これはずっと遅いです。それが私の現在のアプローチです。

良い方法がありますか?

+0

「はるかに遅い」とはどういう意味ですか? –

+0

これらのオブジェクトは非常に深くネストされる傾向があるので、要求ごとにこれらの大きなツリーをステップ実行することは理想的ではありません。 – user1456632

+0

ホワイトリスト作成はどのように機能すると思いますか?構造を踏み込むことは避けられません。 –

答えて

0

このような何か: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 

シンボルにキーを変換するように行うことができるいくつかの改善は、おそらくあり、あなたを伝えるために、より良いエラーメッセージを持っていますネストレベルに欠けているキーなどがあります。

関連する問題