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 

Вы увидите, что выше references кусок params не обрабатываются точно так же, как и остальные параметры. В ближайшее время появятся более противоречивые краевые дела. И единственный способ, которым я знаю, как бороться с ними, - это разблокировать мой код внутри этой функции. Скоро это будет беспорядочно!

Итак, как мне теперь отредактировать этот код? Куда мне идти, чтобы справиться с этой сложностью? Должен ли я использовать сотрудничающие объекты (ParamsBuilder или QueryManager) и какую-то стратегию полиморфизма?

Я хотел бы сохранить мой код простым и функциональным как можно больше.

+0

У вас есть пример для параметров и конечной точки, и что должно быть возвращено методом? –

ответ

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 

В принципе, у вас есть два типа параметров: те, которые вы должны пройти как (как :limit,), и те, вы превратить

Бывший только прошли через (как :include.) , последние преобразуются с использованием списка lambdas, указанного в самом начале этого фрагмента.

Поскольку вы использовали to_query в оригинальный вопрос, я предлагаю вам использовать rails, следовательно, у вас есть blank? метод под рукой и нет необходимости явно проверить пустые строки и/или нулей.

На последнем этапе мы отвергаем пробелы и присоединяемся ко всем с амперсандом.

+0

Итак, вы предлагаете мне разделить каждый вид стратегии разбора на свой собственный тип, выраженный как лямбда? Затем я передаю результаты в виде массива в конвейер запросов и т. Д.? Это то, что здесь происходит? –

+0

См. Обновление. – mudasobwa

Смежные вопросы