модуль 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
Иногда у вас есть ресурс, который клиенты всегда ищут без ссылки на ID. Распространенный пример: /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' => 'posts#show' post 'post/:id' => 'posts#create_comment'
Теперь, если вы отправите POST-запрос на /posts/:id, он будет перенаправлен на действие create_comment. GET-запрос на тот же URL перенаправится на действие show.
Если ваш маршрут должен отвечать на более чем один метод HTTP (или все методы), то использование опции :via в match предпочтительнее.
match 'post/:id' => 'posts#show', via: [:get, :post]
Именованные маршруты
Маршруты могут быть именованными, передав опцию :as, что позволяет легко ссылаться внутри вашего кода как на name_of_route_url для полного URL и name_of_route_path для URI-пути.
Пример:
# In config/routes.rb get '/login' => '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, маршрут просто именуется по имени метода, который вы вызываете на блочном параметре, а не map.
# In config/routes.rb controller :blog do get 'blog/show' => :list get 'blog/delete' => :delete get 'blog/edit' => :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' => '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' => :show, constraints: {
postalcode: /\d{5}(-\d{4})?/
}
end
Ограничения могут включать модификаторы регулярного выражения 'ignorecase' и 'extended syntax':
controller 'geocode' do
get 'geocode/:postalcode' => :show, constraints: {
postalcode: /hx\d\d\s\d[a-z]{2}/i
}
end
controller 'geocode' do
get 'geocode/:postalcode' => :show, constraints: {
postalcode: /# Postalcode format
\d{5} #Prefix
(-\d{4})? #Suffix
/x
}
end
Использование модификатора multiline вызовет ArgumentError. Модификаторы регулярных выражений Encoding игнорируются. Сопоставление всегда будет использовать кодировку по умолчанию или ASCII.
Внешние перенаправления
Вы можете перенаправить любой путь на другой путь, используя вспомогательную функцию перенаправления в своем маршрутизаторе:
get "/stories" => redirect("/posts")
Маршруты с символами Unicode
Вы можете указать маршруты с символами Unicode в своем маршрутизаторе:
get "こんにちは" => "welcome#index"
Маршрутизация к приложениям Rack
Вместо строки, как posts#index, которая соответствует действию index в контроллере PostsController, вы можете указать любое приложение Rack в качестве конечной точки для соответствия:
get "/application.js" => 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 к команде.
© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.