Jak mogę znaleźć aktualną trasę w Railsach?

211

Muszę znać bieżącą trasę w filtrze w Railsach. Jak mogę dowiedzieć się, co to jest?

Korzystam z zasobów REST i nie widzę nazwanych tras.

luca
źródło
3
Co próbujesz z tym osiągnąć? Kiedy mówisz „trasa”, masz na myśli „URI”?
jdl
wszelkie przemyślenia, jak zdobyć je w oprogramowaniu pośrednim .
Saurabh

Odpowiedzi:

197

Aby znaleźć identyfikator 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"

Aby znaleźć trasę, tj. Kontroler, akcję i parametry:

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
Swanand
źródło
2
Czy wiesz, czy jest to ten sam / właściwy sposób, aby to zrobić w Rails 3? Jestem pewien, że nadal jest dostępny, ale chcę mieć pewność, że przestrzegam najnowszych konwencji.
Jan
37
Aktualny kontroler i działanie są zawsze dostępne w params[:controller]i params[:action]. Jednak poza tym, jeśli chcesz rozpoznać trasę, ten interfejs API nie jest już dostępny. Teraz się zmieniło ActionDispatch::Routingi jeszcze tego nie wypróbowałem recognize_path.
Swanand
38
Lepiej jest użyć request.pathdo znalezienia bieżącej ścieżki.
Daniel Brockman,
2
Możesz także zadzwonić w request.env['ORIGINAL_FULLPATH']celu włączenia możliwych parametrów do ścieżki, zobacz moją odpowiedź poniżej.
DuArme,
2
current_uri = request.env ['PATH_INFO'] nie działa, jeśli trailing_slash jest ustawiony na trasach
Gediminas
297

Jeśli próbujesz specjalną skrzynkę w widoku, możesz użyć current_page?jak w:

<% if current_page?(:controller => 'users', :action => 'index') %>

... lub akcja i identyfikator ...

<% if current_page?(:controller => 'users', :action => 'show', :id => 1) %>

... lub nazwana trasa ...

<% if current_page?(users_path) %>

...i

<% if current_page?(user_path(1)) %>

Ponieważ current_page?wymaga zarówno kontrolera, jak i akcji, kiedy zależy mi tylko na kontrolerze, tworzę current_controller?metodę w ApplicationController:

  def current_controller?(names)
    names.include?(current_controller)
  end

I użyj tego w ten sposób:

<% if current_controller?('users') %>

... który działa również z wieloma nazwami kontrolerów ...

<% if current_controller?(['users', 'comments']) %>
IAmNaN
źródło
27
Pamiętaj, że możesz także użyć bieżącej strony? o nazwanych trasach: current_page? (users_path)
tothemario 9.09.11
Niezły totemario. Nie wiedziałem tego Zmieniam odpowiedź.
IAmNaN
zwraca adres jest prawdziwy cokolwiek "/ użytkownicy", "/ Users /", "/ użytkowników smth = sdfasf?" .... Czasem nie tak dobrze w praktyce
Gediminas
4
controller_namei action_namesą dobre do użycia w pomocnikach i widokach tego typu rzeczy.
Matt Connolly
1
W widoku możesz również zrobić <% if params [: action] == 'show'%>, więc nie potrzebujesz kontrolera
rmcsharry
150

Najprostsze rozwiązanie, jakie mogę wymyślić w 2015 r. (Zweryfikowane przy użyciu Rails 4, ale powinno również działać przy użyciu Rails 3)

request.url
# => "http://localhost:3000/lists/7/items"
request.path
# => "/lists/7/items"
weltschmerz
źródło
1
A jeśli chcesz mieć identyfikator w widoku: <% = request.path_parameters [: id]%>
rmcsharry
To jest niesamowite! Użyj tego w częściowej formie, aby przekierować na bieżącą stronę z nowymi parametrami. <form action="<%= request.path %>">
xHocquet
19

Możesz to zrobić

Rails.application.routes.recognize_path "/your/path"

Działa dla mnie w szynach 3.1.0.rc4

Lucas Renan
źródło
11

W szynach 3 można uzyskać dostęp do obiektu Rack :: Mount :: RouteSet za pośrednictwem obiektu Rails.application.routes, a następnie wywołać rozpoznawanie bezpośrednio na nim

route, match, params = Rails.application.routes.set.recognize(controller.request)

która otrzymuje pierwsze (najlepsze) dopasowanie, następująca pętla formularza blokuje pasujące trasy:

Rails.application.routes.set.recognize(controller.request) do |r, m, p|
  ... do something here ...
end

gdy już znajdziesz trasę, możesz uzyskać nazwę trasy poprzez route.name. Jeśli chcesz uzyskać nazwę trasy dla określonego adresu URL, a nie bieżącą ścieżkę żądania, musisz wyodrębnić fałszywy obiekt żądania, aby przekazać go do szafy, sprawdź ActionController :: Routing :: Routes.recognize_path, aby zobaczyć jak oni to robią.

KinOfCain
źródło
5
Błąd:undefined method 'recognize' for #<Journey::Routes:0x007f893dcfa648>
fguillen,
7

Na podstawie sugestii @AmNaN (więcej szczegółów):

class ApplicationController < ActionController::Base

 def current_controller?(names)
  names.include?(params[:controller]) unless params[:controller].blank? || false
 end

 helper_method :current_controller?

end

Teraz możesz to nazwać np. W układzie nawigacyjnym, aby oznaczyć elementy listy jako aktywne:

<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>

Dla tras usersi wystarczyłoby:alertscurrent_page?

 current_page?(users_path)
 current_page?(alerts_path)

Ale przy zagnieżdżonych trasach i żądaniach dotyczących wszystkich działań kontrolera (porównywalnych z items) current_controller?była dla mnie lepsza metoda:

 resources :users do 
  resources :items
 end

Pierwsza pozycja menu jest w ten sposób aktywna dla następujących tras:

   /users/x/items        #index
   /users/x/items/x      #show
   /users/x/items/new    #new
   /users/x/items/x/edit #edit
noworodek
źródło
4

Zakładam, że masz na myśli identyfikator 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

Zgodnie z komentarzem poniżej, jeśli potrzebujesz nazwy kontrolera, możesz po prostu to zrobić:

  private
    def pre_process
      self.controller_name        #  Will return "order"
      self.controller_class_name  # Will return "OrderController"
    end
Aaron Rustad
źródło
tak, zrobiłem to, ale miałem lepszą nadzieję. Potrzebuję wiedzieć, który kontroler został wywołany, ale mam dość skomplikowane zagnieżdżone zasoby. Request.path_parameters ('kontroler') nie wydaje mi się działać poprawnie.
luca
Nie ma potrzeby self.w self.controller_nameiself.controller_class_name
Weltschmerz
4

Jeśli potrzebujesz również parametrów :

current_fullpath = request.env ['ORIGINAL_FULLPATH']
# Jeśli przeglądasz http://example.com/my/test/path?param_n=N 
# wtedy current_fullpath wskaże na „/ my / test / path? param_n = N”

I pamiętaj, że zawsze możesz zadzwonić <%= debug request.env %>w widoku, aby zobaczyć wszystkie dostępne opcje.

DuArme
źródło
4

request.url

request.path # aby uzyskać ścieżkę oprócz podstawowego adresu URL

Charles Skariah
źródło
2

Możesz zobaczyć wszystkie trasy poprzez prowizję: trasy (może ci to pomóc).

James Schorr
źródło
Wolę otworzyć nową kartę z niepoprawną ścieżką i wyświetlić wszystkie ścieżki / trasy z przeglądarki, ponieważ są ładniejsze w ten sposób. Ale nie sądzę, żeby to pomogło uzyskać aktualną trasę.
ahnbizcad
0

Możesz zrobić, request.env['REQUEST_URI']aby zobaczyć pełny żądany identyfikator URI .. wyświetli on coś takiego jak poniżej

http://localhost:3000/client/1/users/1?name=test
Vbp
źródło
0

Możesz to zrobić:

def active_action?(controller)
   'active' if controller.remove('/') == controller_name
end

Teraz możesz użyć w ten sposób:

<%= link_to users_path, class: "some-class #{active_action? users_path}" %>
Tiago Cassio
źródło