модуль ActionDispatch::Routing
Модуль маршрутизации предоставляет перенаправление URL в чистом Ruby. Это способ перенаправить входящие запросы к контроллерам и действиям. Он заменяет правила mod_rewrite. Главное, что маршрутизация Rails работает с любым веб-сервером. Маршруты определяются в config/routes.rb.
Представьте создание маршрутов как построение карты для ваших запросов. Карта указывает, куда им нужно идти, основываясь на предварительно определённом шаблоне:
Rails.application.routes.draw do Pattern 1 tells some request to go to one place Pattern 2 tell them to go to another ... end
Следующие символы являются специальными:
:controller maps to your controller name :action maps to an action with your controllers
Другие имена просто отображаются как параметр, как в случае с :id.
Ресурсы
Маршрутизация ресурсов позволяет быстро объявлять все стандартные маршруты для заданного контроллера ресурсов. Вместо объявления отдельных маршрутов для ваших index, show, new, edit, create, update и destroy действий, маршрут ресурсов объявляет их в одной строке кода:
resources :photos
Иногда у вас есть ресурс, который клиенты всегда ищут без ссылки на идентификатор. Общий пример: /profile всегда отображает профиль текущего пользователя, вошедшего в систему. В этом случае можно использовать одиночный ресурс для отображения /profile (вместо /profile/:id) в действии show.
resource :profile
Часто встречаются ресурсы, которые логически являются дочерними ресурсами других ресурсов:
resources :magazines do resources :ads end
Вы можете организовать группы контроллеров под пространством имён. Чаще всего вы можете сгруппировать ряд административных контроллеров под пространством имён admin. Вы размещаете эти контроллеры в каталоге app/controllers/admin, и можете сгруппировать их вместе в своём маршрутизаторе:
namespace "admin" do resources :posts, :comments end
В качестве альтернативы можно добавить префиксы к вашему пути, не используя отдельный каталог, используя scope. scope принимает дополнительные параметры, которые применяются ко всем включённым маршрутам.
scope path: "/cpanel", as: 'admin' do resources :posts, :comments end
Для получения более подробной информации, см. Routing::Mapper::Resources#resources, Routing::Mapper::Scoping#namespace, и Routing::Mapper::Scoping#scope.
Маршруты, не являющиеся ресурсами
Для маршрутов, которые не подходят под модель resources, можно использовать методы помощников HTTP get, post, patch, put и delete.
get 'post/:id', to: 'posts#show' post 'post/:id', to: 'posts#create_comment'
Теперь, если вы отправите POST-запрос на /posts/:id, он будет перенаправлен на действие create_comment. GET-запрос на тот же URL будет перенаправлен на действие show.
Если ваш маршрут должен отвечать на несколько методов HTTP (или на все методы), то использование опции :via в match предпочтительнее.
match 'post/:id', to: 'posts#show', via: [:get, :post]
Именованные маршруты
Маршруты можно именовать, передав опцию :as, что позволяет легко ссылаться на них в вашем коде как на name_of_route_url для полного URL и name_of_route_path для пути URI.
Пример:
# In config/routes.rb get '/login', to: 'accounts#login', as: 'login' # With render, redirect_to, tests, etc. redirect_to login_url
Аргументы также могут быть переданы.
redirect_to show_item_path(id: 25)
Используйте root в качестве сокращения для именования маршрута для корневого пути «/».
# In config/routes.rb
root to: 'blogs#index'
# would recognize http://www.example.com/ as
params = { controller: 'blogs', action: 'index' }
# and provide these named routes
root_url # => 'http://www.example.com/'
root_path # => '/'
Примечание: при использовании controller, маршрут просто именуется по методу, который вы вызываете на параметре блока, а не по карте.
# In config/routes.rb controller :blog do get 'blog/show', to: :list get 'blog/delete', to: :delete get 'blog/edit', to: :edit end # provides named routes for show, delete, and edit link_to @article.title, blog_show_path(id: @article.id)
Красивые URL-адреса
Маршруты могут генерировать красивые URL-адреса. Например:
get '/articles/:year/:month/:day', to: 'articles#find_by_id', constraints: {
year: /\d{4}/,
month: /\d{1,2}/,
day: /\d{1,2}/
}
Используя маршрут выше, URL «localhost:3000/articles/2005/11/06» сопоставляется с
params = {year: '2005', month: '11', day: '06'}
Регулярные выражения и параметры
Вы можете указать регулярное выражение, чтобы определить формат параметра.
controller 'geocode' do
get 'geocode/:postalcode', to: :show, constraints: {
postalcode: /\d{5}(-\d{4})?/
}
end
Ограничения могут включать модификаторы регулярных выражений 'ignorecase' и 'extended syntax':
controller 'geocode' do
get 'geocode/:postalcode', to: :show, constraints: {
postalcode: /hx\d\d\s\d[a-z]{2}/i
}
end
controller 'geocode' do
get 'geocode/:postalcode', to: :show, constraints: {
postalcode: /# Postalcode format
\d{5} #Prefix
(-\d{4})? #Suffix
/x
}
end
Использование модификатора multiline вызовет ArgumentError. Модификаторы кодирования регулярных выражений игнорируются. Сопоставление всегда будет использовать кодировку по умолчанию или ASCII.
Внешние перенаправления
Вы можете перенаправить любой путь на другой путь, используя помощник перенаправления в своём маршрутизаторе:
get "/stories", to: redirect("/posts")
Маршруты с символами Юникода
Вы можете указать маршруты с символами Юникода в своём маршрутизаторе:
get "こんにちは", to: "welcome#index"
Routing к приложениям Rack
Вместо String, такого как posts#index, который соответствует действию index в PostsController, вы можете указать любое приложение Rack в качестве конечной точки для сопоставления:
get "/application.js", to: Sprockets
Перезагрузка маршрутов
Вы можете перезагрузить маршруты, если это необходимо:
Rails.application.reload_routes!
Это очистит все именованные маршруты и перезагрузит config/routes.rb, если файл был изменён с момента последней загрузки. Чтобы выполнить абсолютную принудительную перезагрузку, используйте reload!.
Тестирование маршрутов
Два основных метода для тестирования маршрутов:
assert_routing
def test_movie_route_properly_splits
opts = {controller: "plugin", action: "checkout", id: "2"}
assert_routing "plugin/checkout/2", opts
end
assert_routing позволяет проверить, правильно ли маршрут преобразуется в параметры.
assert_recognizes
def test_route_has_options
opts = {controller: "plugin", action: "show", id: "12"}
assert_recognizes opts, "/plugins/show/12"
end
Обратите внимание на тонкое различие между ними: assert_routing проверяет, соответствует ли URL параметрам, а assert_recognizes проверяет, правильно ли URL разбивается на параметры.
В тестах вы можете просто передать URL или именованный маршрут в get или post.
def send_to_jail get '/jail' assert_response :success end def goes_to_login get login_url #... end
Просмотр списка всех ваших маршрутов
rails routes
Направьте запрос к конкретному контроллеру с помощью -c, или используйте grep для маршрутов с помощью -g. Полезно в сочетании с --expanded, которое отображает маршруты вертикально.
© 2004–2020 David Heinemeier Hansson
Licensed under the MIT License.