Necesito saber la ruta actual en un filtro en Rails. ¿Cómo puedo saber de qué se trata?
Estoy haciendo recursos REST y no veo rutas con nombre.
Necesito saber la ruta actual en un filtro en Rails. ¿Cómo puedo saber de qué se trata?
Estoy haciendo recursos REST y no veo rutas con nombre.
Respuestas:
Para descubrir el URI:
current_uri = request.env['PATH_INFO']
# If you are browsing http://example.com/my/test/path,
# then above line will yield current_uri as "/my/test/path"
Para averiguar la ruta, es decir, controlador, acción y parámetros:
path = ActionController::Routing::Routes.recognize_path "/your/path/here/"
# ...or newer Rails versions:
#
path = Rails.application.routes.recognize_path('/your/path/here')
controller = path[:controller]
action = path[:action]
# You will most certainly know that params are available in 'params' hash
params[:controller]
y params[:action]
. Sin embargo, fuera de él, si desea reconocer la ruta, esta API ya no está disponible. Ahora ha cambiado ActionDispatch::Routing
y todavía no lo he probado recognize_path
.
request.path
para encontrar la ruta actual.
request.env['ORIGINAL_FULLPATH']
para incluir los posibles parámetros en la ruta, vea mi respuesta a continuación.
Si está intentando poner algo especial en una vista, puede usarlo current_page?
como en:
<% if current_page?(:controller => 'users', :action => 'index') %>
... o una acción e id ...
<% if current_page?(:controller => 'users', :action => 'show', :id => 1) %>
... o una ruta con nombre ...
<% if current_page?(users_path) %>
...y
<% if current_page?(user_path(1)) %>
Debido a que current_page?
requiere un controlador y una acción, cuando me preocupo solo por el controlador, hago un current_controller?
método en ApplicationController:
def current_controller?(names)
names.include?(current_controller)
end
Y úsalo así:
<% if current_controller?('users') %>
... que también funciona con múltiples nombres de controlador ...
<% if current_controller?(['users', 'comments']) %>
controller_name
y action_name
son buenos para usar en ayudantes y vistas para este tipo de cosas también.
La solución más simple que puedo encontrar en 2015 (verificado con Rails 4, pero también debería funcionar con Rails 3)
request.url
# => "http://localhost:3000/lists/7/items"
request.path
# => "/lists/7/items"
<form action="<%= request.path %>">
Puedes hacerlo
Rails.application.routes.recognize_path "/your/path"
A mí me funciona en rails 3.1.0.rc4
En rails 3 puede acceder al objeto Rack :: Mount :: RouteSet a través del objeto Rails.application.routes, luego llame a reconocer en él directamente
route, match, params = Rails.application.routes.set.recognize(controller.request)
que obtiene la primera (mejor) coincidencia, la siguiente forma de bloque recorre las rutas coincidentes:
Rails.application.routes.set.recognize(controller.request) do |r, m, p|
... do something here ...
end
una vez que tenga la ruta, puede obtener el nombre de la ruta a través de route.name. Si necesita obtener el nombre de la ruta para una URL en particular, no la ruta de solicitud actual, deberá simular un objeto de solicitud falso para pasar al bastidor, consulte ActionController :: Routing :: Routes.recognize_path para ver cómo lo están haciendo.
undefined method 'recognize' for #<Journey::Routes:0x007f893dcfa648>
Basado en la sugerencia de @AmNaN (más detalles):
class ApplicationController < ActionController::Base
def current_controller?(names)
names.include?(params[:controller]) unless params[:controller].blank? || false
end
helper_method :current_controller?
end
Ahora puede llamarlo, por ejemplo, en un diseño de navegación para marcar elementos de la lista como activos:
<ul class="nav nav-tabs">
<li role="presentation" class="<%= current_controller?('items') ? 'active' : '' %>">
<%= link_to user_items_path(current_user) do %>
<i class="fa fa-cloud-upload"></i>
<% end %>
</li>
<li role="presentation" class="<%= current_controller?('users') ? 'active' : '' %>">
<%= link_to users_path do %>
<i class="fa fa-newspaper-o"></i>
<% end %>
</li>
<li role="presentation" class="<%= current_controller?('alerts') ? 'active' : '' %>">
<%= link_to alerts_path do %>
<i class="fa fa-bell-o"></i>
<% end %>
</li>
</ul>
Para las rutas users
y alerts
, current_page?
sería suficiente:
current_page?(users_path)
current_page?(alerts_path)
Pero con rutas anidadas y solicitud de todas las acciones de un controlador (comparable con items
), current_controller?
fue el mejor método para mí:
resources :users do
resources :items
end
La primera entrada del menú está activa de esa manera para las siguientes rutas:
/users/x/items #index
/users/x/items/x #show
/users/x/items/new #new
/users/x/items/x/edit #edit
O, más elegantemente: request.path_info
Asumiré que te refieres al URI:
class BankController < ActionController::Base
before_filter :pre_process
def index
# do something
end
private
def pre_process
logger.debug("The URL" + request.url)
end
end
Según su comentario a continuación, si necesita el nombre del controlador, simplemente puede hacer esto:
private
def pre_process
self.controller_name # Will return "order"
self.controller_class_name # Will return "OrderController"
end
self.
en self.controller_name
eself.controller_class_name
Si también necesita los parámetros :
current_fullpath = request.env ['ORIGINAL_FULLPATH'] # Si está navegando http://example.com/my/test/path?param_n=N # entonces current_fullpath apuntará a "/ my / test / path? param_n = N"
Y recuerde que siempre puede llamar <%= debug request.env %>
desde una vista para ver todas las opciones disponibles.
request.url
request.path # para obtener la ruta excepto la url base
Puede ver todas las rutas a través de rake: rutas (esto podría ayudarlo).
Puedes hacerlo:
def active_action?(controller)
'active' if controller.remove('/') == controller_name
end
Ahora, puedes usar así:
<%= link_to users_path, class: "some-class #{active_action? users_path}" %>