Разбор строки маршрутизации в стиле Rails с использованием только Journey
Учитывая это определение отображения:/order/:meal/:cheese
Разобрать эту строку /order/hamburger/american
в {meal:'hamburger', cheese:'american'}
,
Я играл с внутренностями Journey, пытаясь выяснить, возможно ли это за пределами рельсов. Есть и другие SO вопросы, которые показывают, как это возможно в Rails, используя признать_path. И я знаю, что вы могли бы легко сделать это с помощью регулярного выражения или разбиения, но я бы хотел, чтобы дополнительные функции разбора были бесплатными (например, форматирование и т. Д.).
Вот то, что работает. Просто интересно, есть ли у кого-нибудь улучшения. Я в основном архивирую / объединяю две части совпадений Journey (имена и записи), чтобы создать хеш совпадений (например, what_path). Просто интересно, кто-нибудь полез в Путешествие и попытался сделать то же самое.
require 'journey'
def hashify_match matches
h = {}
matches.names.each_with_index do |key, i|
h[key.to_sym] = matches.captures[i]
end
h
end
pattern = Journey::Path::Pattern.new '/order/(:meal(/:cheese))'
matches = pattern.match '/order/hamburger/american'
puts hashify_match matches
matches = pattern.match '/order/hotdog/cheddar'
puts hashify_match matches
Вот что распечатывает.
{:meal=>"hamburger", :cheese=>"american"}
{:meal=>"hotdog", :cheese=>"cheddar"}
Есть ли другая часть Journey, которую я мог бы использовать для создания хеша матча? Увидеть, matches.names
а также matches.captures
действительно являются объектами Array, и это похоже на взлом. Конечно, какая-то часть Rails соединяет их вместе в какой-то момент.
Обратите внимание, что используется только самоцвет Journey (включен в Rails 3.2.0+).
1 ответ
Journey::Router делает это здесь:
match_data = r.path.match(req.path_info)
match_names = match_data.names.map { |n| n.to_sym }
match_values = match_data.captures.map { |v| v && Utils.unescape_uri(v) }
info = Hash[match_names.zip(match_values).find_all { |_,y| y }]
Так что не похоже, что есть удобный способ сделать то, что вы пытаетесь сделать.