Spec-Zone.ru › Ruby on Rails 6.0

модуль 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', 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"

Маршрутизация к приложениям Rack

Вместо строки, например 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–2019 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API