Rails daki mevcut rotayı nasıl bulabilirim?


212

Raylar'daki bir filtrede geçerli rotayı bilmem gerekiyor. Ne olduğunu nasıl öğrenebilirim?

REST kaynakları yapıyorum ve adlandırılmış rota görmüyorum.


3
Bununla ne yapmaya çalışıyorsunuz? "Güzergah" derken "URI" demek istedin?
jdl

ara katman yazılımı almak için herhangi bir düşünce .
Saurabh

Yanıtlar:


197

URI'yı bulmak için:

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"

Rotayı, yani kontrolör, eylem ve parametreler bulmak için:

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

2
Bunun Rails 3'te yapmanın aynı / doğru yolu olup olmadığını biliyor musunuz? Eminim hala erişilebilir, ancak sadece en son sözleşmelere bağlı olduğumdan emin olmak istiyorum.
John

37
Geçerli denetleyici ve eylem her zaman mevcuttur params[:controller]ve params[:action]. Ancak, bunun dışında, rotayı tanımak istiyorsanız, bu API artık kullanılamamaktadır. Şimdi değişti ActionDispatch::Routingve henüz denemedim recognize_path.
Swanand

38
request.pathGeçerli yolu bulmak için kullanmak daha iyidir .
Daniel Brockman

2
Ayrıca request.env['ORIGINAL_FULLPATH'], olası parametreleri yola dahil etmek için arayabilirsiniz , aşağıdaki cevabımı görün.
DuArme

2
current_uri = request.env ['PATH_INFO'] rotalarda trailing_slash ayarlanırsa çalışmaz
Gediminas

297

Bir görünümde özel bir şey yapmaya çalışıyorsanız, aşağıdaki gibi kullanabilirsiniz current_page?:

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

... ya da bir eylem ve kimlik ...

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

... ya da adlandırılmış bir rota ...

<% if current_page?(users_path) %>

...ve

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

Çünkü current_page?bir denetleyici ve eylemi hem gerektirir Sadece denetleyicisi umurumda, ben bir hale current_controller?ApplicationController yöntemi:

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

Ve şu şekilde kullanın:

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

... aynı zamanda birden fazla denetleyici adıyla da çalışır ...

<% if current_controller?(['users', 'comments']) %>

27
Current_page'i de kullanabileceğinizi unutmayın? belirtilen rotalarla: current_page? (users_path)
tothemario

Güzel bir senaryo. Bunu bilmiyordum. Cevabı değiştiriyorum.
IAmNaN

adres "/ users", "/ users /", "/ users? smth = sdfasf" olursa olsun doğru döndürür .... Bazen pratikte çok iyi bir şey değil
Gediminas

4
controller_nameve action_namebu tür şeyler için yardımcılar ve görünümlerde kullanmak için iyidir.
Matt Connolly

1
Bir görünümde ayrıca params [: action] == 'show'%> ise <% yapabilirsiniz, böylece denetleyiciye ihtiyacınız yoktur
rmcsharry

151

2015 yılında karşılaşabileceğim en basit çözüm (Rails 4 kullanılarak doğrulandı, ancak Rails 3 kullanılarak da çalışmalı)

request.url
# => "http://localhost:3000/lists/7/items"
request.path
# => "/lists/7/items"

1
Ve görünümde kimliği istiyorsanız: <% = request.path_parameters [: id]%>
rmcsharry

Bu harika! Geçerli sayfaya yeni parametrelerle yönlendirmek için bunu kısmi bir biçimde kullanın. <form action="<%= request.path %>">
xHocquet

19

Bunu yapabilirsiniz

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

Benim için raylar 3.1.0.rc4 çalışır


11

Rails 3'te Rack :: Mount :: RouteSet nesnesine Rails.application.routes nesnesi üzerinden erişebilir ve ardından doğrudan tanıma işlevini çağırabilirsiniz

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

ilk (en iyi) eşleşmeyi elde eden şu blok formu eşleşen rotaların üzerinden geçer:

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

Rotayı aldıktan sonra, rota adını route.name aracılığıyla alabilirsiniz. Geçerli istek yolunu değil, belirli bir URL'nin yol adını almanız gerekiyorsa, rafa geçmek için sahte bir istek nesnesini taklit etmeniz gerekir, görmek için ActionController :: Routing :: Routes.recognize_path nasıl yapıyorlar.


5
Hata:undefined method 'recognize' for #<Journey::Routes:0x007f893dcfa648>
fguillen

7

@AmNaN önerisine dayanarak (daha fazla ayrıntı):

class ApplicationController < ActionController::Base

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

 helper_method :current_controller?

end

Artık listeyi aktif olarak işaretlemek için bir gezinme düzeninde arayabilirsiniz:

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

İçin usersve alertsyolları current_page?yeterli olacaktır:

 current_page?(users_path)
 current_page?(alerts_path)

Ancak iç içe yollar ve bir denetleyicinin tüm eylemleri için istekle (karşılaştırılabilir items), current_controller?benim için daha iyi bir yöntemdi:

 resources :users do 
  resources :items
 end

İlk menü girişi aşağıdaki yollar için bu şekilde aktiftir:

   /users/x/items        #index
   /users/x/items/x      #show
   /users/x/items/new    #new
   /users/x/items/x/edit #edit


4

URI demek istediğini varsayacağım:

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

Aşağıdaki yorumunuza göre, denetleyicinin adına ihtiyacınız varsa, bunu yapabilirsiniz:

  private
    def pre_process
      self.controller_name        #  Will return "order"
      self.controller_class_name  # Will return "OrderController"
    end

evet bunu yaptım, ama daha iyi bir şekilde umuyordum. İhtiyacım olan hangi denetleyicinin çağrıldığını bilmek, ama oldukça karmaşık iç içe kaynaklara sahibim .. request.path_parameters ('denetleyici') bana düzgün çalışmıyor gibi görünüyor.
luca

Gerek yok self.içinde self.controller_nameveself.controller_class_name
weltschmerz

4

Parametrelere de ihtiyacınız varsa :

current_fullpath = request.env ['ORIGINAL_FULLPATH']
# Http://example.com/my/test/path?param_n=N 
# sonra current_fullpath "/ my / test / path? param_n = N"

Ve <%= debug request.env %>mevcut tüm seçenekleri görmek için her zaman bir görünümde arama yapabileceğinizi unutmayın .



2

Tüm güzergahları tırmıkla görebilirsiniz: güzergahlar (bu size yardımcı olabilir).


Geçersiz bir yolla yeni bir sekme açmayı ve tarayıcıdaki tüm yolu / rotaları görmeyi tercih ediyorum, çünkü bu şekilde daha güzeller. Ama bunun mevcut rotayı elde etmeye yardımcı olduğunu düşünmüyorum.
ahnbizcad

0

request.env['REQUEST_URI']Tam istenen URI'yi görmek için yapabilirsiniz .. aşağıdaki gibi bir çıktı verecektir

http://localhost:3000/client/1/users/1?name=test

0

Bunu yapabilirsiniz:

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

Şimdi şöyle kullanabilirsiniz:

<%= link_to users_path, class: "some-class #{active_action? users_path}" %>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.