Поиск…


Вступление

Маршрутизатор Rails распознает URL-адреса и отправляет их в действие контроллера. Он также может генерировать пути и URL-адреса, избегая необходимости жестких строк в ваших представлениях.

замечания

«Маршрутизация» в целом - это то, как URL-адреса «обрабатываются» вашим приложением. В случае Rails обычно это контроллер, и какое действие этого контроллера будет обрабатывать определенный входящий URL. В приложениях Rails маршруты обычно помещаются в файл config/routes.rb .

Маршрутизация ресурсов (основная)

Маршруты определяются в config/routes.rb . Они часто определяются как группа связанных маршрутов, используя resources или методы resource .

resources :users создают следующие семь маршрутов, все сопоставление с действиями UsersController :

get       '/users',          to: 'users#index'
post      '/users',          to: 'users#create'
get       '/users/new',      to: 'users#new'
get       '/users/:id/edit', to: 'users#edit'
get       '/users/:id',      to: 'users#show'
patch/put '/users/:id',      to: 'users#update'
delete    '/users/:id',      to: 'users#destroy'

Названия действий отображаются после # в to параметра выше. Методы с теми же именами должны быть определены в app/controllers/users_controller.rb следующим образом:

class UsersController < ApplicationController
  def index
  end

  def create
  end

  # continue with all the other methods…
end

Вы можете ограничить действия, которые генерируются only или except :

resources :users, only:   [:show]
resources :users, except: [:show, :index]

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

5.0
$ rake routes
5.0
$ rake routes
# OR
$ rails routes
users     GET    /users(.:format)          users#index
          POST   /users(.:format)          users#create
new_user  GET    /users/new(.:format)      users#new
edit_user GET    /users/:id/edit(.:format) users#edit
user      GET    /users/:id(.:format)      users#show
          PATCH  /users/:id(.:format)      users#update
          PUT    /users/:id(.:format)      users#update
          DELETE /users/:id(.:format)      users#destroy

Чтобы увидеть только маршруты, которые отображаются на конкретный контроллер:

5.0
$ rake routes -c static_pages
static_pages_home    GET    /static_pages/home(.:format)    static_pages#home
static_pages_help    GET    /static_pages/help(.:format)    static_pages#help
5.0
$ rake routes -c static_pages
static_pages_home    GET    /static_pages/home(.:format)    static_pages#home
static_pages_help    GET    /static_pages/help(.:format)    static_pages#help

# OR

$ rails routes -c static_pages
static_pages_home    GET    /static_pages/home(.:format)    static_pages#home
static_pages_help    GET    /static_pages/help(.:format)    static_pages#help

Вы можете выполнять поиск по маршрутам с помощью опции -g . Это показывает любой маршрут, который частично соответствует имени вспомогательного метода, URL-адресу или HTTP-глаголу:

5.0
$ rake routes -g new_user     # Matches helper method
$ rake routes -g POST         # Matches HTTP Verb POST 
5.0
$ rake routes -g new_user     # Matches helper method
$ rake routes -g POST         # Matches HTTP Verb POST 
# OR
$ rails routes -g new_user    # Matches helper method
$ rails routes -g POST        # Matches HTTP Verb POST 

Кроме того, при запуске сервера rails в режиме разработки вы можете получить доступ к веб-странице, которая отображает все ваши маршруты с фильтром поиска, соответствующим приоритету сверху вниз, в <hostname>/rails/info/routes . Это будет выглядеть так:

помощник HTTP-глагол Дорожка Контроллер # Действие
Путь / URL [Матч по пути]
users_path ПОЛУЧИТЬ /users(.:format) пользователи индекс #
СООБЩЕНИЕ /users(.:format) пользователей # создать
new_user_path ПОЛУЧИТЬ /users/new(.:format) пользователи # новых
edit_user_path ПОЛУЧИТЬ /users/:id/edit(.:format) пользователи # редактировать
user_path ПОЛУЧИТЬ /users/:id(.:format) Пользователи # показать
PATCH /users/:id(.:format) пользователи # обновление
ПОЛОЖИЛ /users/:id(.:format) пользователи # обновление
УДАЛЯТЬ /users/:id(.:format) пользователей # уничтожить

Маршруты могут быть объявлены доступными только для членов (а не коллекций) с использованием resource метода вместо resources в routes.rb . С resource маршрут index создается не по умолчанию, а только при явном запросе такого типа:

resource :orders, only: [:index, :create, :show]

Ограничения

Вы можете фильтровать маршруты, используя ограничения.

Существует несколько способов использования ограничений, в том числе:

Например, запрошенное ограничение на ограничение позволяет только конкретному IP-адресу разрешить доступ к маршруту:

constraints(ip: /127\.0\.0\.1$/) do
  get 'route', to: "controller#action"
end

См. Другие аналогичные примеры ActionDispatch :: Routing :: Mapper :: Scoping .

Если вы хотите сделать что-то более сложное, вы можете использовать более сложные ограничения и создать класс для переноса логики:

# lib/api_version_constraint.rb
class ApiVersionConstraint
  def initialize(version:, default:)
    @version = version
    @default = default
  end

  def version_header
    "application/vnd.my-app.v#{@version}"
  end

  def matches?(request)
    @default || request.headers["Accept"].include?(version_header)
  end
end

# config/routes.rb
require "api_version_constraint"

Rails.application.routes.draw do
  namespace :v1, constraints: ApiVersionConstraint.new(version: 1, default: true) do
    resources :users # Will route to app/controllers/v1/users_controller.rb
  end

  namespace :v2, constraints: ApiVersionConstraint.new(version: 2) do
    resources :users # Will route to app/controllers/v2/users_controller.rb
  end
end

Одна форма, несколько кнопок отправки

Вы также можете использовать значение тегов отправки формы как ограничение для перехода к другому действию. Если у вас есть форма с несколькими кнопками отправки (например, «предварительный просмотр» и «отправка»), вы можете зафиксировать это ограничение непосредственно на своих routes.rb вместо того, чтобы писать javascript для изменения URL-адреса формы. Например, с камнем commit_param_routing вы можете воспользоваться rails submit_tag

Первый параметр Rails submit_tag позволяет изменить значение параметра фиксации формы

# app/views/orders/mass_order.html.erb
<%= form_for(@orders, url: mass_create_order_path do |f| %>
    <!-- Big form here -->
  <%= submit_tag "Preview" %>
  <%= submit_tag "Submit" %>
  # => <input name="commit" type="submit" value="Preview" />
  # => <input name="commit" type="submit" value="Submit" />
  ...
<% end %>

# config/routes.rb
resources :orders do
  # Both routes below describe the same POST URL, but route to different actions 
  post 'mass_order', on: :collection, as: 'mass_order',
    constraints: CommitParamRouting.new('Submit'), action: 'mass_create' # when the user presses "submit"
  post 'mass_order', on: :collection,
    constraints: CommitParamRouting.new('Preview'), action: 'mass_create_preview' # when the user presses "preview"
  # Note the `as:` is defined only once, since the path helper is mass_create_order_path for the form url
  # CommitParamRouting is just a class like ApiVersionContraint
end

Маршрутные маршруты

Rails предоставляет несколько способов организации ваших маршрутов.

Объем по URL-адресу :

scope 'admin' do
  get 'dashboard', to: 'administration#dashboard'
  resources 'employees'
end

Это генерирует следующие маршруты

get       '/admin/dashboard',          to: 'administration#dashboard'
post      '/admin/employees',          to: 'employees#create'
get       '/admin/employees/new',      to: 'employees#new'
get       '/admin/employees/:id/edit', to: 'employees#edit'
get       '/admin/employees/:id',      to: 'employees#show'
patch/put '/admin/employees/:id',      to: 'employees#update'
delete    '/admin/employees/:id',      to: 'employees#destroy'

На стороне сервера может иметь смысл хранить некоторые представления в другой подпапке, чтобы отделять просмотры администраторов от пользовательских представлений.

Объем по модулю

scope module: :admin do
  get 'dashboard', to: 'administration#dashboard'
end

module ищет файлы контроллера под подпапкой данного имени

get       '/dashboard',          to: 'admin/administration#dashboard'

Вы можете переименовать префикс помощника пути, добавив параметр as

scope 'admin', as: :administration do
  get 'dashboard'
end

# => administration_dashboard_path

Rails обеспечивает удобный способ сделать все вышеописанное, используя метод namespace . Следующие объявления эквивалентны

namespace :admin do
end

scope 'admin', module: :admin, as: :admin

Область применения контроллера

scope controller: :management do
  get 'dashboard'
  get 'performance'
end

Это генерирует эти маршруты

get       '/dashboard',          to: 'management#dashboard'
get       '/performance',        to: 'management#performance'

Неглубокое гнездование

Маршруты ресурсов допускают :shallow параметр, который помогает, по возможности, сократить URL-адреса. Ресурсы не должны быть вложены более чем на один уровень. Один из способов избежать этого - создать мелкие маршруты. Цель состоит в том, чтобы оставить сегменты сегментов родительской коллекции, где они не нужны. Конечным результатом является то, что только генерируемые вложенные маршруты предназначены для :index :create и :new действий. Остальные сохраняются в собственном неглубоком контексте URL. Существует два варианта возможностей для настраиваемых неглубоких маршрутов:

  • : shallow_path: Префикс пути элемента с заданным параметром

    scope shallow_path: "sekret" do
      resources :articles do
        resources :comments, shallow: true
      end
    end
    
  • : shallow_prefix : добавьте указанные параметры в именованные помощники

    scope shallow_prefix: "sekret" do
      resources :articles do
        resources :comments, shallow: true
      end
    end
    

Мы также можем проиллюстрировать shallow маршруты:

resources :auctions, shallow: true do
  resources :bids do
   resources :comments
  end
end 

альтернативно кодируется следующим образом (если вы счастливы с блоком):

resources :auctions do
 shallow do
   resources :bids do
     resources :comments
   end
 end
end

Результирующие маршруты:

Префикс глагол Шаблон URI
bid_comments ПОЛУЧИТЬ /bids/:bid_id/comments(.:format)
СООБЩЕНИЕ /bids/:bid_id/comments(.:format)
new_bid_comment ПОЛУЧИТЬ /bids/:bid_id/comments/new(.:format)
edit_comment ПОЛУЧИТЬ /comments/:id/edit(.:format)
комментарий ПОЛУЧИТЬ /comments/:id(.:format)
PATCH /comments/:id(.:format)
ПОЛОЖИЛ /comments/:id(.:format)
УДАЛЯТЬ /comments/:id(.:format)
auction_bids ПОЛУЧИТЬ /auctions/:auction_id/bids(.:format)
СООБЩЕНИЕ /auctions/:auction_id/bids(.:format)
new_auction_bid ПОЛУЧИТЬ /auctions/:auction_id/bids/new(.:format)
edit_bid ПОЛУЧИТЬ /bids/:id/edit(.:format)
предложение ПОЛУЧИТЬ /bids/:id(.:format)
PATCH /bids/:id(.:format)
ПОЛОЖИЛ /bids/:id(.:format)
УДАЛЯТЬ /bids/:id(.:format)
аукционы ПОЛУЧИТЬ /auctions(.:format)
СООБЩЕНИЕ /auctions(.:format)
new_auction ПОЛУЧИТЬ /auctions/new(.:format)
edit_auction ПОЛУЧИТЬ /auctions/:id/edit(.:format)
торг ПОЛУЧИТЬ /auctions/:id(.:format)
PATCH /auctions/:id(.:format)
ПОЛОЖИЛ /auctions/:id(.:format)
УДАЛЯТЬ /auctions/:id(.:format)

Если вы тщательно проанализируете маршруты, вы заметите, что вложенные части URL-адреса включены только тогда, когда они необходимы для определения того, какие данные будут отображаться.

Обеспокоенность

Чтобы избежать повторения на вложенных маршрутах, проблемы обеспечивают отличный способ совместного использования общих ресурсов, которые можно повторно использовать. Чтобы создать беспокойство использовать метод concern внутри routes.rb файла. Метод ожидает символ и блок:

concern :commentable do
  resources :comments
end

Не создавая никаких маршрутов, этот код позволяет использовать атрибут :concerns ресурса. Самый простой пример:

resource :page, concerns: :commentable

Эквивалентный вложенный ресурс будет выглядеть так:

resource :page do
  resource :comments
end

Это создало бы, например, следующие маршруты:

/pages/#{page_id}/comments
/pages/#{page_id}/comments/#{comment_id}

Чтобы проблемы были значимыми, необходимо наличие нескольких ресурсов, которые используют эту проблему. Дополнительные ресурсы могут использовать любой из следующих синтаксисов для вызова проблемы:

resource :post, concerns: %i(commentable)
resource :blog do
  concerns :commentable
end

Перенаправление

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

4,0
get '/stories', to: redirect('/posts')
4,0
match "/abc" => redirect("http://example.com/abc")

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

4,0
match '*path' => redirect('/'), via: :get
# or
get '*path' => redirect('/')
4,0
match '*path' => redirect('/')

Маршруты участников и коллекций

Определение блока-члена внутри ресурса создает маршрут, который может действовать на отдельном члене этого маршрута на основе ресурсов:

resources :posts do
  member do
    get 'preview'
  end
end

Это генерирует следующий маршрут участника:

get '/posts/:id/preview', to: 'posts#preview'
# preview_post_path

Маршруты сбора позволяют создавать маршруты, которые могут действовать в коллекции объектов ресурсов:

resources :posts do
  collection do
    get 'search'
  end
end

Это создает следующий маршрут сбора:

get '/posts/search', to: 'posts#search'
# search_posts_path

Альтернативный синтаксис:

resources :posts do
  get 'preview', on: :member
  get 'search',  on: :collection
end

URL-параметры с периодом

Если вы хотите поддерживать параметр url более сложным, чем номер id, вы можете столкнуться с проблемой с парсером, если значение содержит период. Все, что следует за периодом, будет считаться форматом (т.е. json, xml).

Вы можете обойти это ограничение, используя ограничение для расширения принятого ввода.

Например, если вы хотите ссылаться на запись пользователя по адресу электронной почты в URL-адресе:

resources :users, constraints: { id: /.*/ }

Корневой маршрут

Вы можете добавить маршрут домашней страницы в свое приложение с помощью root метода.

# config/routes.rb
Rails.application.routes.draw do
  root "application#index"
  # equivalent to:
  # get "/", "application#index"  
end

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  def index
    render "homepage"
  end
end

А в терминале rake routes ( rake routes rails routes в Rails 5) будут производить:

root     GET    /         application#index

Поскольку главная страница, как правило, является самым важным маршрутом, а маршруты приоритетны в том порядке, в котором они появляются, root маршрут обычно должен быть первым в вашем файле маршрутов.

Дополнительные действия RESTful

resources :photos do
  member do
    get 'preview'
  end
  collection do
    get 'dashboard'
  end
end

Это создает следующие маршруты в дополнение к маршрутам RESTful по умолчанию 7 :

get       '/photos/:id/preview',          to: 'photos#preview'
get       '/photos/dashboards',           to: 'photos#dashboard'

Если вы хотите сделать это для отдельных строк, вы можете использовать:

resources :photos do
  get 'preview',   on: :member
  get 'dashboard', on: :collection
end

Вы также можете добавить действие к /new пути:

resources :photos do
  get 'preview', on: :new
end

Что создаст:

get       '/photos/new/preview',          to: 'photos#preview'

Будьте внимательны при добавлении действий на маршруты RESTful, возможно, вам не хватает другого ресурса!

Область доступных областей

Если ваше приложение доступно на разных языках, вы обычно показываете текущую локаль в URL-адресе.

scope '/(:locale)', locale: /#{I18n.available_locales.join('|')}/ do
    root 'example#root'
    # other routes
end

Ваш корень будет доступен через локали, определенные в I18n.available_locales .

Смонтировать другое приложение

mount используется для монтирования другого приложения (в основном, стойки) или рельсовых двигателей, которые будут использоваться в текущем приложении

синтаксис:

mount SomeRackApp, at: "some_route"

Теперь вы можете получить доступ к установленному выше приложению с помощью вспомогательного маршрута some_rack_app_path или some_rack_app_url .

Но если вы хотите переименовать это имя помощника, вы можете сделать это как:

mount SomeRackApp, at: "some_route", as: :myapp

Это создаст myapp_path и myapp_url помощники, которые можно использовать для перехода к этому подключенному приложению.

Перенаправления и подстановочные маршруты

Если вы хотите предоставить URL-адрес из удобства для своего пользователя, но сопоставьте его напрямую с другим, который вы уже используете. Используйте перенаправление:

# config/routes.rb
TestApp::Application.routes.draw do
  get 'courses/:course_name' => redirect('/courses/%{course_name}/lessons'), :as => "course"
end

Ну, это стало интересно быстро. Основной принцип здесь заключается в том, чтобы просто использовать метод #redirect для отправки одного маршрута на другой маршрут. Если ваш маршрут довольно прост, это действительно простой метод. Но если вы хотите также отправить исходные параметры, вам нужно сделать немного гимнастики, взяв параметр внутри %{here} . Обратите внимание на одиночные кавычки вокруг всего.

В приведенном выше примере мы также переименовали маршрут для удобства, используя псевдоним с параметром: as. Это позволяет использовать это имя в методах, таких как помощники #_path. Опять же, проверьте свои $ rake routes с вопросами.

Разделить маршруты на несколько файлов

Если ваш файл маршрутов чрезвычайно большой, вы можете поместить свои маршруты в несколько файлов и включить каждый из файлов с помощью метода require_relative Ruby:

config/routes.rb :
YourAppName::Application.routes.draw do
  require_relative 'routes/admin_routes'
  require_relative 'routes/sidekiq_routes'
  require_relative 'routes/api_routes'
  require_relative 'routes/your_app_routes'
end
config/routes/api_routes.rb :
YourAppName::Application.routes.draw do
  namespace :api do
    # ...
  end
end

Вложенные маршруты

Если вы хотите добавить вложенные маршруты, вы можете написать следующий код в routes.rb .

resources :admins do
  resources :employees
end

Это создаст следующие маршруты:

     admin_employees GET      /admins/:admin_id/employees(.:format)            employees#index
                     POST     /admins/:admin_id/employees(.:format)            employees#create
  new_admin_employee GET      /admins/:admin_id/employees/new(.:format)        employees#new
 edit_admin_employee GET      /admins/:admin_id/employees/:id/edit(.:format)   employees#edit
      admin_employee GET      /admins/:admin_id/employees/:id(.:format)        employees#show
                     PATCH    /admins/:admin_id/employees/:id(.:format)        employees#update
                     PUT      /admins/:admin_id/employees/:id(.:format)        employees#update
                     DELETE   /admins/:admin_id/employees/:id(.:format)        employees#destroy
              admins GET      /admins(.:format)                                admins#index
                     POST     /admins(.:format)                                admins#create
           new_admin GET      /admins/new(.:format)                            admins#new
          edit_admin GET      /admins/:id/edit(.:format)                       admins#edit
               admin GET      /admins/:id(.:format)                            admins#show
                     PATCH    /admins/:id(.:format)                            admins#update
                     PUT      /admins/:id(.:format)                            admins#update
                     DELETE   /admins/:id(.:format)                            admins#destroy


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow