J'ai besoin de connaître l'itinéraire actuel dans un filtre dans Rails. Comment puis-je savoir ce que c'est?
Je fais des ressources REST et je ne vois aucune route nommée.
J'ai besoin de connaître l'itinéraire actuel dans un filtre dans Rails. Comment puis-je savoir ce que c'est?
Je fais des ressources REST et je ne vois aucune route nommée.
Réponses:
Pour connaître l'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"
Pour connaître l'itinéraire, c'est-à-dire le contrôleur, l'action et les paramètres:
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]
et params[:action]
. Cependant, en dehors de celui-ci, si vous souhaitez reconnaître l'itinéraire, cette API n'est plus disponible. Il est maintenant passé à ActionDispatch::Routing
et je ne l'ai pas encore essayé recognize_path
.
request.path
pour trouver le chemin actuel.
request.env['ORIGINAL_FULLPATH']
pour inclure les paramètres possibles dans le chemin d'accès, voir ma réponse ci-dessous.
Si vous essayez de cas spécial quelque chose dans une vue, vous pouvez utiliser current_page?
comme dans:
<% if current_page?(:controller => 'users', :action => 'index') %>
... ou une action et id ...
<% if current_page?(:controller => 'users', :action => 'show', :id => 1) %>
... ou un itinéraire nommé ...
<% if current_page?(users_path) %>
...et
<% if current_page?(user_path(1)) %>
Parce que current_page?
nécessite à la fois un contrôleur et une action, lorsque je me soucie uniquement du contrôleur, je crée une current_controller?
méthode dans ApplicationController:
def current_controller?(names)
names.include?(current_controller)
end
Et utilisez-le comme ceci:
<% if current_controller?('users') %>
... qui fonctionne également avec plusieurs noms de contrôleurs ...
<% if current_controller?(['users', 'comments']) %>
controller_name
et action_name
sont bons pour une utilisation dans les aides et les vues pour ce genre de chose aussi.
Solution la plus simple que j'ai pu trouver en 2015 (vérifiée avec Rails 4, mais devrait également fonctionner avec Rails 3)
request.url
# => "http://localhost:3000/lists/7/items"
request.path
# => "/lists/7/items"
<form action="<%= request.path %>">
Tu peux le faire
Rails.application.routes.recognize_path "/your/path"
Cela fonctionne pour moi dans les rails 3.1.0.rc4
Dans les rails 3, vous pouvez accéder à l'objet Rack :: Mount :: RouteSet via l'objet Rails.application.routes, puis appeler reconnaître directement dessus
route, match, params = Rails.application.routes.set.recognize(controller.request)
qui obtient la première (meilleure) correspondance, la forme de bloc suivante fait une boucle sur les routes correspondantes:
Rails.application.routes.set.recognize(controller.request) do |r, m, p|
... do something here ...
end
une fois que vous avez l'itinéraire, vous pouvez obtenir le nom de l'itinéraire via route.name. Si vous devez obtenir le nom de la route pour une URL particulière, pas le chemin de demande actuel, vous devrez alors simuler un faux objet de demande à transmettre au rack, consultez ActionController :: Routing :: Routes.recognize_path pour voir comment ils le font.
undefined method 'recognize' for #<Journey::Routes:0x007f893dcfa648>
Basé sur la suggestion @AmNaN (plus de détails):
class ApplicationController < ActionController::Base
def current_controller?(names)
names.include?(params[:controller]) unless params[:controller].blank? || false
end
helper_method :current_controller?
end
Vous pouvez maintenant l'appeler, par exemple dans une disposition de navigation pour marquer les éléments de la liste comme actifs:
<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>
Pour les routes users
et alerts
, current_page?
cela suffirait:
current_page?(users_path)
current_page?(alerts_path)
Mais avec des routes imbriquées et une demande pour toutes les actions d'un contrôleur (comparable à items
), current_controller?
c'était la meilleure méthode pour moi:
resources :users do
resources :items
end
La première entrée de menu est ainsi activée pour les itinéraires suivants:
/users/x/items #index
/users/x/items/x #show
/users/x/items/new #new
/users/x/items/x/edit #edit
Ou, plus élégamment: request.path_info
Source:
demande de documentation en rack
Je suppose que vous voulez dire l'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
Selon votre commentaire ci-dessous, si vous avez besoin du nom du contrôleur, vous pouvez simplement le faire:
private
def pre_process
self.controller_name # Will return "order"
self.controller_class_name # Will return "OrderController"
end
self.
dans self.controller_name
etself.controller_class_name
Si vous avez également besoin des paramètres :
current_fullpath = request.env ['ORIGINAL_FULLPATH'] # Si vous parcourez http://example.com/my/test/path?param_n=N # alors current_fullpath pointera vers "/ mon / test / chemin? param_n = N"
Et n'oubliez pas que vous pouvez toujours appeler <%= debug request.env %>
dans une vue pour voir toutes les options disponibles.
request.url
request.path #pour obtenir le chemin sauf l'URL de base
Vous pouvez voir toutes les routes via rake: routes (cela pourrait vous aider).
Tu peux le faire:
def active_action?(controller)
'active' if controller.remove('/') == controller_name
end
Maintenant, vous pouvez utiliser comme ceci:
<%= link_to users_path, class: "some-class #{active_action? users_path}" %>