2016-12-27 3 views
0

ルビーの宝石で私は入力として特定の既知のクエリパラメータを受け取り、それらをクエリ文字列にマッサージし、そのデータを取得するための残りのエンドポイントとしてその構築された(URL)文字列を使用する必要があります。データ処理の小さな不一致に対処するためにどのようなプログラミングパターンや戦略を使用すべきですか?

入力が奇妙なものになりました。コードを入力して一貫した出力に正規化するようにしています。

def build_query(params, endpoint) 
     limit  = Hash[limit:  params[:limit] || 0] 
     skip  = Hash[skip:  params[:skip] || 0] 
     asc  = Hash[asc:  params[:asc]  || ""] 
     desc  = Hash[desc:  params[:desc] || ""] 

     query = [limit, skip, asc, desc].select { |hash| hash.values.none? { |val| val == '' || val == 0 } } 
     encoded = query.map{ |q| q.to_query }.join("&") 

     references = build_references(params[:include]) || "" 

     query_string = references.empty? ? "#{endpoint}#{encoded}" : "#{endpoint}#{references}&#{encoded}" 
    end 

あなたはparamsreferences片が残りのパラメータと同じように扱われていないことの上に表示されます。間もなくエッジのケースが少しずつ矛盾しています。そして、私がこれらを処理する方法を知っている唯一の方法は、この関数の中で自分のコードをフォークすることです。それはすぐに乱雑になるだろう!

このコードをどのようにリファクタリングする必要がありますか?この複雑さを管理するためにここからどこに行くべきですか?コラボレーションオブジェクト(ParamsBuilderまたはQueryManager)と何らかの多型戦略を使用する必要がありますか?

コードをできるだけ単純で機能的に保ちたいと思います。

+0

paramsとエンドポイントの例がありますが、そのメソッドから返されるものは何ですか? –

答えて

3
plain = %i|limit skip asc desc| # plain values 
built = { include: ->(input) { build_references(input) } } # procs 

query = (plain | built).map do |p| 
    case p 
    when Symbol then params[p] 
    when Array then p.last.(params[p.first]) 
    end 
end.reject(&:blank?).map(&:to_query).join("&") 

[endpoint, query].join 

は基本的に、あなたは2種類のパラメータがあります:あなたがあるとして通過しているものを(のような:limit、)とそれらを、あなたが変換している

元だけを通過されている(よう:includeを。)後者は、このスニペットの最初に指定されたラムダのリストを使用して変換されます。

あなたは元の質問でto_queryを使用していたので、私はそれゆえ、あなたが手にblank?メソッドを持っており、明示的に空の文字列および/またはゼロのためにチェックする必要はありません、あなたはrailsを使用することをお勧め。

最後のステップでは、空白を拒否し、すべてをアンパサンドで結合します。

+0

それで、パンクング戦略のそれぞれの種類をラムダとして表現された独自の型に分けることを提案していますか?次に、結果を配列としてクエリパイプラインなどにパイプします。それはここで起こっているのでしょうか? –

+0

アップデートをご覧ください。 – mudasobwa

関連する問題