Buscar..


Introducción

El enrutador Rails reconoce las URL y las envía a la acción de un controlador. También puede generar rutas y direcciones URL, evitando la necesidad de cadenas de código en sus vistas.

Observaciones

En general, "enrutamiento" es cómo las URL son "manejadas" por su aplicación. En el caso de Rails, generalmente es qué controlador y qué acción de ese controlador manejará una URL entrante en particular. En las aplicaciones de Rails, las rutas generalmente se ubican en el archivo config/routes.rb .

Enrutamiento de recursos (básico)

Las rutas se definen en config/routes.rb . A menudo se definen como un grupo de rutas relacionadas, utilizando los resources o resource métodos de resource .

resources :users crean las siguientes siete rutas, todas UsersController a las acciones de 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'

Nombres de las acciones se muestran después de la # en el to parámetro anterior. Los métodos con esos mismos nombres se deben definir en app/controllers/users_controller.rb siguiente manera:

class UsersController < ApplicationController
  def index
  end

  def create
  end

  # continue with all the other methods…
end

Puede limitar las acciones que se generan con only o except :

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

Puede ver todas las rutas de su aplicación en cualquier momento ejecutando:

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

Para ver solo las rutas que se asignan a un controlador en particular:

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

Puedes buscar a través de rutas usando la opción -g . Esto muestra cualquier ruta que coincida parcialmente con el nombre del método auxiliar, la ruta de la URL o el verbo 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 

Además, al ejecutar el servidor de rails en modo de desarrollo, puede acceder a una página web que muestra todas sus rutas con un filtro de búsqueda, con prioridad de arriba a abajo, en <hostname>/rails/info/routes . Se verá así:

Ayudante Verbo HTTP Camino Controlador # Acción
Camino / Url [Match Path]
ruta_usuario OBTENER /users(.:format) índice de usuarios #
ENVIAR /users(.:format) usuarios # crear
new_user_path OBTENER /users/new(.:format) usuarios # nuevo
edit_user_path OBTENER /users/:id/edit(.:format) usuarios # editar
ruta_usuario OBTENER /users/:id(.:format) usuarios # show
PARCHE /users/:id(.:format) usuarios # actualizar
PONER /users/:id(.:format) usuarios # actualizar
BORRAR /users/:id(.:format) usuarios # destruir

Las rutas se pueden declarar disponibles solo para miembros (no para colecciones) utilizando el resource del método en lugar de los resources en routes.rb . Con resource , una ruta de index no se crea de forma predeterminada, sino solo cuando se solicita explícitamente una como esta:

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

Restricciones

Puede filtrar qué rutas están disponibles usando restricciones.

Hay varias formas de usar restricciones, incluyendo:

Por ejemplo, una restricción basada solicitada para permitir solo una dirección IP específica para acceder a una ruta:

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

Vea otros ejemplos similares ActionDispatch :: Routing :: Mapper :: Scoping .

Si desea hacer algo más complejo, puede usar restricciones más avanzadas y crear una clase para envolver la lógica:

# 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

Una forma, varios botones de enviar

También puede utilizar el valor de las etiquetas de envío de un formulario como una restricción para enrutar a una acción diferente. Si tiene un formulario con varios botones de envío (por ejemplo, "vista previa" y "envío"), podría capturar esta restricción directamente en su routes.rb , en lugar de escribir javascript para cambiar la URL de destino del formulario. Por ejemplo, con la gema commit_param_routing puede aprovechar las ventajas de rails submit_tag

submit_tag primer parámetro de Rails submit_tag permite cambiar el valor de su parámetro de confirmación de formulario

# 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

Rutas de alcance

Rails te ofrece varias formas de organizar tus rutas.

Alcance por URL :

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

Esto genera las siguientes rutas.

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'

Puede tener más sentido, en el lado del servidor, mantener algunas vistas en una subcarpeta diferente, para separar las vistas de administrador de las vistas de los usuarios.

Alcance por módulo

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

module busca los archivos del controlador en la subcarpeta del nombre dado

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

Puede cambiar el nombre del prefijo de los ayudantes de ruta agregando un parámetro as

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

# => administration_dashboard_path

Rails proporciona una manera conveniente de hacer todo lo anterior, utilizando el método de namespace . Las siguientes declaraciones son equivalentes.

namespace :admin do
end

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

Alcance por controlador

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

Esto genera estas rutas.

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

Anidación poco profunda

Las rutas de recursos aceptan una opción :shallow que ayuda a acortar las URL cuando sea posible. Los recursos no deben estar anidados a más de un nivel de profundidad. Una forma de evitar esto es mediante la creación de rutas poco profundas. El objetivo es dejar de lado los segmentos de URL de colección principal donde no son necesarios. El resultado final es que las únicas rutas anidadas generadas son para :index :create y :new . El resto se mantienen en su propio contexto de URL superficial. Hay dos opciones de alcance para personalizar rutas poco profundas:

  • : shallow_path: Prefiere las rutas de los miembros con un parámetro específico

    scope shallow_path: "sekret" do
      resources :articles do
        resources :comments, shallow: true
      end
    end
    
  • : shallow_prefix : Agrega parámetros especificados a los ayudantes nombrados

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

También podemos ilustrar rutas shallow más por:

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

codificado alternativamente de la siguiente manera (si está satisfecho con el bloque):

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

Las rutas resultantes son:

Prefijo Verbo Patrón de URI
bid_comments OBTENER /bids/:bid_id/comments(.:format)
ENVIAR /bids/:bid_id/comments(.:format)
new_bid_comment OBTENER /bids/:bid_id/comments/new(.:format)
Editar comentario OBTENER /comments/:id/edit(.:format)
comentario OBTENER /comments/:id(.:format)
PARCHE /comments/:id(.:format)
PONER /comments/:id(.:format)
BORRAR /comments/:id(.:format)
remate de ofertas OBTENER /auctions/:auction_id/bids(.:format)
ENVIAR /auctions/:auction_id/bids(.:format)
new_auction_bid OBTENER /auctions/:auction_id/bids/new(.:format)
edit_bid OBTENER /bids/:id/edit(.:format)
oferta OBTENER /bids/:id(.:format)
PARCHE /bids/:id(.:format)
PONER /bids/:id(.:format)
BORRAR /bids/:id(.:format)
subastas OBTENER / subastas (. formato)
ENVIAR / subastas (. formato)
nueva_aucción OBTENER /auctions/new(.:format)
edición_aucción OBTENER /auctions/:id/edit(.:format)
subasta OBTENER /auctions/:id(.:format)
PARCHE /auctions/:id(.:format)
PONER /auctions/:id(.:format)
BORRAR /auctions/:id(.:format)

Si analiza las rutas generadas con cuidado, notará que las partes anidadas de la URL solo se incluyen cuando son necesarias para determinar qué datos mostrar.

Preocupaciones

Para evitar la repetición en rutas anidadas, las preocupaciones proporcionan una excelente manera de compartir recursos comunes que son reutilizables. Para crear una preocupación utilice el método de concern dentro de la routes.rb archivo. El método espera un símbolo y un bloque:

concern :commentable do
  resources :comments
end

Aunque no crea ninguna ruta en sí, este código permite usar el atributo :concerns en un recurso. El ejemplo más simple sería:

resource :page, concerns: :commentable

El recurso anidado equivalente se vería así:

resource :page do
  resource :comments
end

Esto construiría, por ejemplo, las siguientes rutas:

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

Para que las preocupaciones sean significativas, debe haber múltiples recursos que utilicen la preocupación. Los recursos adicionales podrían usar cualquiera de la siguiente sintaxis para llamar a la inquietud:

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

Redireccion

Puede realizar la redirección en las rutas de Rails de la siguiente manera:

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

También puede redirigir todas las rutas desconocidas a una ruta determinada:

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

Miembro y rutas de recogida

La definición de un bloque miembro dentro de un recurso crea una ruta que puede actuar sobre un miembro individual de esa ruta basada en recursos:

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

Esto genera la siguiente ruta de miembro:

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

Las rutas de recolección permiten crear rutas que pueden actuar sobre una colección de objetos de recursos:

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

Esto genera la siguiente ruta de recolección:

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

Una sintaxis alternativa:

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

URLs params con un punto

Si desea admitir un parámetro url más complejo que un número de identificación, puede tener problemas con el analizador si el valor contiene un punto. Se asumirá que todo lo que sigue a un período es un formato (es decir, json, xml).

Puede solucionar esta limitación utilizando una restricción para ampliar la entrada aceptada.

Por ejemplo, si desea hacer referencia a un registro de usuario por dirección de correo electrónico en la url:

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

Ruta de la raíz

Puede agregar una ruta de página de inicio a su aplicación con el método 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

Y en la terminal, las rake routes ( rails routes en Rails 5) producirán:

root     GET    /         application#index

Debido a que la página principal suele ser la ruta más importante, y las rutas se priorizan en el orden en que aparecen, la ruta root debería ser la primera en su archivo de rutas.

Acciones adicionales de REST

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

Esto crea las siguientes rutas además de las 7 rutas RESTful predeterminadas :

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

Si desea hacer esto para líneas simples, puede usar:

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

También puede agregar una acción a la /new ruta:

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

Que creará:

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

Tenga en cuenta al agregar acciones a sus rutas RESTful, ¡es probable que le falte otro recurso!

Ámbito local disponible

Si su aplicación está disponible en diferentes idiomas, normalmente muestra la configuración regional actual en la URL.

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

Se podrá acceder a su raíz a través de las configuraciones regionales definidas en I18n.available_locales .

Montar otra aplicación

el montaje se utiliza para montar otra aplicación (básicamente, la aplicación en bastidor) o los rieles de los motores que se utilizarán dentro de la aplicación actual

sintaxis:

mount SomeRackApp, at: "some_route"

Ahora puede acceder a la aplicación montada anteriormente usando el ayudante de ruta some_rack_app_path o some_rack_app_url .

Pero si desea cambiar el nombre de este ayudante, puede hacerlo como:

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

Esto generará los ayudantes myapp_path y myapp_url que se pueden usar para navegar a esta aplicación montada.

Redirecciones y rutas de comodines

Si desea proporcionar una URL por conveniencia para su usuario pero asignarla directamente a otra que ya esté usando. Utilice una redirección:

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

Bueno, eso se puso interesante rápido. El principio básico aquí es simplemente usar el método #redirect para enviar una ruta a otra. Si su ruta es bastante simple, es un método muy sencillo. Pero si también desea enviar los parámetros originales, necesita hacer un poco de gimnasia capturando el parámetro dentro de %{here} . Tenga en cuenta las comillas simples alrededor de todo.

En el ejemplo anterior, también hemos cambiado el nombre de la ruta por conveniencia utilizando un alias con el: como parámetro. Esto nos permite usar ese nombre en métodos como los ayudantes #_path. De nuevo, prueba tus $ rake routes con preguntas.

Dividir rutas en múltiples archivos

Si su archivo de rutas es abrumadoramente grande, puede poner sus rutas en múltiples archivos e incluir cada uno de los archivos con el método require_relative de 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

Rutas anidadas

Si desea agregar rutas anidadas, puede escribir el siguiente código en el archivo routes.rb .

resources :admins do
  resources :employees
end

Esto generará las siguientes rutas:

     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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow