Spec-Zone.ru › Ruby on Rails 4.2

модуль ActionDispatch::Routing

Модуль маршрутизации предоставляет перенаправление URL в чистом Руби. Это способ перенаправить входящие запросы к контроллерам и действиям. Он заменяет правила 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' => 'posts#show'
post 'post/:id' => 'posts#create_comment'

Если вашему маршруту нужно реагировать на более одного HTTP-метода (или все методы), то предпочтительнее использовать опцию :via в match.

match 'post/:id' => 'posts#show', via: [:get, :post]

Теперь, если вы отправите POST-запрос на /posts/:id, он будет перенаправлен на действие create_comment. GET-запрос на тот же URL будет перенаправлен на действие show.

Именованные маршруты

Маршруты можно именовать, передав опцию :as, что позволяет легко ссылаться на них в исходном коде как на name_of_route_url для полного URL и name_of_route_path для пути URI.

Пример:

# In 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 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 routes.rb
controller :blog do
  get 'blog/show'     => :list
  get 'blog/delete'   => :delete
  get 'blog/edit/:id' => :edit
end

# provides named routes for show, delete, and edit
link_to @article.title, 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})?/
  }

Ограничения могут включать модификаторы регулярных выражений «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: /# Postcode format
       \d{5} #Prefix
       (-\d{4})? #Suffix
       /x
  }
end

Использование модификатора multiline вызовет ArgumentError. Модификаторы регулярных выражений Encoding игнорируются. Сопоставление всегда будет использовать кодировку по умолчанию или ASCII.

Внешние перенаправления

Вы можете перенаправить любой путь на другой путь, используя помощник перенаправления в своём маршрутизаторе:

get "/stories" => redirect("/posts")

Маршруты с символами Юникода

Вы можете указать маршруты с символами Юникода в своём маршрутизаторе:

get "こんにちは" => "welcome#index"

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

Вместо строки, как posts#index, которая соответствует действию index в PostsController, вы можете указать любое приложение Rack как конечную точку для соответствия:

get "/application.js" => Sprockets

Перезагрузка маршрутов

Вы можете перезагрузить маршруты, если сочтёте это необходимым:

Rails.application.reload_routes!

Это очистит все именованные маршруты и перезагрузит 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
  assert_template "jail/front"
end

def goes_to_login
  get login_url
  #...
end

Просмотр списка всех ваших маршрутов

rake routes

Для указания конкретных контроллеров добавьте префикс к команде CONTROLLER=x.

© 2004–2016 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

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