在ruby Gem中,我写的我必须将作为输入某些已知查询参数并将其按摩到查询字符串中,然后将构造的(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
您会在上面看到params
的references
部分的处理方式与其他参数的处理方式不同。即将到来的边缘案例有些不一致。我知道如何处理这些方法的唯一方法是将我的代码置于此功能中。它将很快变得凌乱!
那么我现在应该如何重构此代码?我应该从这里去哪里管理这种复杂性?我应该使用协作对象(ParamsBuilder
或QueryManager
)和某种多态性策略吗?
我想尽可能简单地保持代码。
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
基本上,您有两种类型的参数:您要通过的参数(例如:limit
),并且要转换(例如:include
。)
刚刚通过,后者是使用本摘要开始时指定的lambdas列表进行了转换的。
由于您在原始问题中使用了to_query
,因此我建议您使用rails
,因此您手头上有blank?
方法,并且无需明确检查空字符串和/或零。
在最后一步中,我们拒绝空白并加入anmpersand。