Eu preciso conhecer a rota atual em um filtro no Rails. Como posso descobrir o que é?
Estou usando recursos REST e não vejo rotas nomeadas.
Eu preciso conhecer a rota atual em um filtro no Rails. Como posso descobrir o que é?
Estou usando recursos REST e não vejo rotas nomeadas.
Respostas:
Para descobrir o 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 descobrir a rota, ou seja, controlador, ação e 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]
e params[:action]
. No entanto, fora dela, se você deseja reconhecer a rota, essa API não está mais disponível. Agora ele mudou ActionDispatch::Routing
e eu ainda não testei recognize_path
.
request.path
para encontrar o caminho atual.
request.env['ORIGINAL_FULLPATH']
para incluir os possíveis parâmetros no caminho, veja minha resposta abaixo.
Se você estiver tentando processar algo especial em uma exibição, poderá usar current_page?
como em:
<% if current_page?(:controller => 'users', :action => 'index') %>
... ou uma ação e id ...
<% if current_page?(:controller => 'users', :action => 'show', :id => 1) %>
... ou uma rota nomeada ...
<% if current_page?(users_path) %>
...e
<% if current_page?(user_path(1)) %>
Como current_page?
requer um controlador e uma ação, quando me preocupo apenas com o controlador, faço um current_controller?
método no ApplicationController:
def current_controller?(names)
names.include?(current_controller)
end
E use-o assim:
<% if current_controller?('users') %>
... que também funciona com vários nomes de controladores ...
<% if current_controller?(['users', 'comments']) %>
controller_name
e action_name
são bons para uso em ajudantes e visualizações para esse tipo de coisa também.
Solução mais simples que eu posso encontrar em 2015 (verificada usando o Rails 4, mas também deve funcionar com o Rails 3)
request.url
# => "http://localhost:3000/lists/7/items"
request.path
# => "/lists/7/items"
<form action="<%= request.path %>">
Você consegue fazer isso
Rails.application.routes.recognize_path "/your/path"
Funciona para mim no Rails 3.1.0.rc4
No trilhos 3, você pode acessar o objeto Rack :: Mount :: RouteSet através do objeto Rails.application.routes e, em seguida, chamar o reconhecimento diretamente
route, match, params = Rails.application.routes.set.recognize(controller.request)
que obtém a primeira (melhor) correspondência, o seguinte formulário de bloco faz um loop nas rotas correspondentes:
Rails.application.routes.set.recognize(controller.request) do |r, m, p|
... do something here ...
end
depois de ter a rota, você pode obter o nome da rota via route.name. Se você precisar obter o nome da rota para uma URL específica, não o caminho da solicitação atual, precisará simular um objeto de solicitação falsa para passar ao rack, confira ActionController :: Routing :: Routes.recognize_path para ver como eles estão fazendo isso.
undefined method 'recognize' for #<Journey::Routes:0x007f893dcfa648>
Com base na sugestão @AmNaN (mais detalhes):
class ApplicationController < ActionController::Base
def current_controller?(names)
names.include?(params[:controller]) unless params[:controller].blank? || false
end
helper_method :current_controller?
end
Agora você pode chamá-lo, por exemplo, em um layout de navegação para marcar itens da lista como ativos:
<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 as rotas users
e alerts
, current_page?
seria suficiente:
current_page?(users_path)
current_page?(alerts_path)
Mas com rotas aninhadas e solicitação de todas as ações de um controlador (comparável a items
), current_controller?
foi o melhor método para mim:
resources :users do
resources :items
end
A primeira entrada do menu é ativada para as seguintes rotas:
/users/x/items #index
/users/x/items/x #show
/users/x/items/new #new
/users/x/items/x/edit #edit
Ou, de maneira mais elegante: request.path_info
Eu vou assumir que você quer dizer o 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
Conforme seu comentário abaixo, se você precisar do nome do controlador, basta fazer o seguinte:
private
def pre_process
self.controller_name # Will return "order"
self.controller_class_name # Will return "OrderController"
end
self.
in self.controller_name
eself.controller_class_name
Você também precisa dos parâmetros :
current_fullpath = request.env ['ORIGINAL_FULLPATH'] # Se você estiver navegando em http://example.com/my/test/path?param_n=N # então current_fullpath apontará para "/ my / test / path? param_n = N"
E lembre-se de que você sempre pode ligar <%= debug request.env %>
para ver todas as opções disponíveis.
request.url
request.path #para obter o caminho, exceto o URL base
Você pode ver todas as rotas via rake: routes (isso pode ajudá-lo).
Você consegue fazer isso:
def active_action?(controller)
'active' if controller.remove('/') == controller_name
end
Agora, você pode usar assim:
<%= link_to users_path, class: "some-class #{active_action? users_path}" %>