ฉันจะค้นหาเส้นทางปัจจุบันใน Rails ได้อย่างไร


211

ฉันจำเป็นต้องรู้เส้นทางปัจจุบันในตัวกรองใน Rails ฉันจะรู้ได้อย่างไรว่ามันคืออะไร?

ฉันกำลังทำแหล่งข้อมูล REST และไม่พบเส้นทางที่ระบุชื่อ


3
คุณพยายามทำอะไรให้สำเร็จ เมื่อคุณพูดว่า "route" คุณหมายถึง "URI" หรือไม่
jdl

ความคิดใด ๆ เกี่ยวกับวิธีการได้รับมันในตัวกลาง
Saurabh

คำตอบ:


197

หากต้องการค้นหา 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"

วิธีค้นหาเส้นทางเช่นคอนโทรลเลอร์, แอ็คชั่นและพารามิเตอร์:

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
คุณจะรู้หรือไม่ว่านี่เป็นวิธีการที่ถูกต้องใน Rails 3 ฉันแน่ใจว่ามันยังคงสามารถเข้าถึงได้ แต่ฉันแค่ต้องการให้แน่ใจว่าฉันปฏิบัติตามอนุสัญญาล่าสุด
จอห์น

37
ควบคุมในปัจจุบันและการกระทำมักจะใช้ได้ในและparams[:controller] params[:action]อย่างไรก็ตามนอกนั้นถ้าคุณต้องการรับรู้เส้นทาง API นี้ไม่สามารถใช้ได้อีกต่อไป ตอนนี้มันเปลี่ยนไปเป็นActionDispatch::Routingและฉันยังไม่ได้ลองrecognize_pathเลย
Swanand

38
มันจะดีกว่าถ้าใช้request.pathเพื่อค้นหาเส้นทางปัจจุบัน
Daniel Brockman

2
คุณสามารถโทรหาrequest.env['ORIGINAL_FULLPATH']เพื่อรวมพารามิเตอร์ที่เป็นไปได้ในเส้นทางดูคำตอบของฉันด้านล่าง
DuArme

2
current_uri = request.env ['PATH_INFO'] ไม่ทำงานหาก trailing_slash ตั้งอยู่ในเส้นทาง
Gediminas

297

หากคุณกำลังพยายามหากรณีพิเศษในมุมมองคุณสามารถใช้current_page?ใน:

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

... หรือการกระทำและรหัส ...

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

... หรือเส้นทางที่มีชื่อ ...

<% if current_page?(users_path) %>

...และ

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

เพราะcurrent_page?ต้องใช้ทั้งคอนโทรลเลอร์และแอ็คชั่นเมื่อฉันสนใจแค่คอนโทรลเลอร์ฉันสร้างcurrent_controller?เมธอดใน ApplicationController:

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

และใช้มันเช่นนี้

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

... ซึ่งใช้งานได้กับชื่อคอนโทรลเลอร์หลายชื่อ ...

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

27
โปรดทราบว่าคุณสามารถใช้ current_page ได้หรือไม่ ด้วยเส้นทางที่มีชื่อ: current_page? (users_path)
tothemario

Nice Tothemario ฉันไม่รู้ ฉันกำลังแก้ไขคำตอบ
IAmNaN

มันกลับเป็นความจริงที่อยู่สิ่งที่เป็น "ผู้ใช้ /", "/ ผู้ใช้ /", "/ ผู้ใช้บ = sdfasf?" .... สิ่งที่บางครั้งไม่ดีดังนั้นในทางปฏิบัติ
Gediminas

4
controller_nameและaction_nameเป็นสิ่งที่ดีสำหรับการใช้งานในผู้ช่วยเหลือและมุมมองสำหรับสิ่งต่าง ๆ เช่นนี้
Matt Connolly

1
ในมุมมองคุณสามารถทำ <% ถ้า params [: action] == 'แสดง'%> ดังนั้นคุณไม่ต้องการคอนโทรลเลอร์
rmcsharry

150

ทางออกที่ง่ายที่สุดที่ฉันสามารถทำได้ในปี 2558 (ตรวจสอบโดยใช้ Rails 4 แต่ควรใช้กับ Rails 3 ด้วย)

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

1
และถ้าคุณต้องการรหัสในมุมมอง: <% = request.path_parameters [: id]%>
rmcsharry

นี่มันเจ๋งมาก! ใช้สิ่งนี้ในรูปแบบบางส่วนเพื่อเปลี่ยนเส้นทางไปยังหน้าปัจจุบันด้วย params ใหม่ <form action="<%= request.path %>">
xHocquet

19

คุณสามารถทำได้

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

มันใช้งานได้สำหรับฉันในราง 3.1.0.rc4


11

ใน Rails 3 คุณสามารถเข้าถึงวัตถุ Rack :: Mount :: RouteSet ผ่านทาง Rails.application.routes object จากนั้นเรียกการรับรู้โดยตรง

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

ที่ได้รับการจับคู่แรก (ดีที่สุด) รูปแบบบล็อกต่อไปนี้จะวนซ้ำไปตามเส้นทางที่ตรงกัน:

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

เมื่อคุณมีเส้นทางคุณจะได้รับชื่อเส้นทางผ่าน route.name หากคุณต้องการรับชื่อเส้นทางสำหรับ URL เฉพาะไม่ใช่เส้นทางคำขอปัจจุบันคุณจะต้องจำลองวัตถุคำขอปลอมเพื่อส่งต่อไปยังชั้นวางดูที่ ActionController :: Routing.recognize_path พวกเขาทำมันอย่างไร


5
ข้อผิดพลาด:undefined method 'recognize' for #<Journey::Routes:0x007f893dcfa648>
fguillen

7

ตามข้อเสนอแนะ @AmNaN (รายละเอียดเพิ่มเติม):

class ApplicationController < ActionController::Base

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

 helper_method :current_controller?

end

ตอนนี้คุณสามารถเรียกมันได้เช่นในเลย์เอาต์การนำทางเพื่อทำเครื่องหมายรายการเป็นใช้งานอยู่:

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

สำหรับusersและalertsเส้นทางcurrent_page?จะเพียงพอ:

 current_page?(users_path)
 current_page?(alerts_path)

แต่ด้วยเส้นทางที่ซ้อนกันและขอให้ทุกการกระทำของตัวควบคุม (เปรียบได้กับitems) current_controller?เป็นวิธีที่ดีกว่าสำหรับฉัน:

 resources :users do 
  resources :items
 end

รายการเมนูแรกคือวิธีที่ใช้งานสำหรับเส้นทางต่อไปนี้:

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


4

ฉันจะถือว่าคุณหมายถึง 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

ตามความคิดเห็นของคุณด้านล่างหากคุณต้องการชื่อของคอนโทรลเลอร์คุณสามารถทำได้:

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

ใช่ฉันทำอย่างนั้น แต่ฉันหวังในวิธีที่ดีกว่า สิ่งที่ฉันต้องการคือการรู้ว่าคอนโทรลเลอร์ใดถูกเรียกใช้ แต่ฉันมีทรัพยากรซ้อนกันที่ซับซ้อน .. request.path_parameters ('controller') ดูเหมือนจะทำงานไม่ถูกต้องสำหรับฉัน
luca

ไม่จำเป็นต้องself.เข้าself.controller_nameและออกself.controller_class_name
weltschmerz

4

หากคุณต้องการพารามิเตอร์ :

current_fullpath = request.env ['ORIGINAL_FULLPATH']
# หากคุณกำลังดู http://example.com/my/test/path?param_n=N 
# จากนั้น current_fullpath จะชี้ไปที่ "/ my / test / path? param_n = N"

และจำไว้ว่าคุณสามารถโทร<%= debug request.env %>ในมุมมองเพื่อดูตัวเลือกที่มีทั้งหมด



2

คุณสามารถดูเส้นทางทั้งหมดผ่าน rake: เส้นทาง (สิ่งนี้อาจช่วยคุณได้)


ฉันต้องการเปิดแท็บใหม่ที่มีเส้นทางที่ไม่ถูกต้องและดูเส้นทาง / เส้นทางทั้งหมดจากเบราว์เซอร์เนื่องจากพวกเขาสวยกว่าด้วยวิธีนั้น แต่ฉันไม่คิดว่าสิ่งนี้จะช่วยให้ได้รับเส้นทางปัจจุบัน
ahnbizcad

0

คุณสามารถทำได้request.env['REQUEST_URI']เพื่อดู URI ที่ขอทั้งหมด .. มันจะแสดงผลบางอย่างดังนี้

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

0

คุณสามารถทำได้:

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

ตอนนี้คุณสามารถใช้สิ่งนี้:

<%= link_to users_path, class: "some-class #{active_action? users_path}" %>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.