Ruby on Rails: получить имя контроллера и действия на основе пути

Я пытаюсь получить имя контроллера и действия на основе пути. У меня есть маршрут:

map.resources :permissions

Я подумал, что могу использовать:

ActionController::Routing::Routes.recognize_path "/permissions/1"

Чтобы получить хеш, например:

{ :controller => "permissions", :action => "show" }

Фактический хеш, который возвращается:

{ :controller => "permissions", :action => "1" }

Как мне получить правильное имя действия, а не только мой переданный идентификатор? Диспетчер должен каким-то образом добраться до этого, иначе Rails не будет работать, но у меня возникли проблемы с определением того, как это делается.


person Community    schedule 11.08.2010    source источник


Ответы (3)


Начиная с Rails 4 метод распознавания пути теперь Rails.application.routes.recognize_path, а не ActionController::Routing::Routes.recognize_path, и он возвращает хэш контроллера, действия и идентификатора, например:

Rails.application.routes.recognize_path(app.edit_somecontroller_path(1))
 => {:controller=>"somecontroller", :action=>"edit", :id=>"1"}
person Fred Willmore    schedule 09.03.2016
comment
Обратите внимание, что этот синтаксис работает, если вызывается из консоли Rails, но когда я вызывал его из application_controller, мне пришлось удалить приложение. из app.edit_somecontroller... часть. Так, например: Rails.application.routes.recognize_path(users_path) - person JosephK; 30.12.2017
comment
Я всегда забываю, как это сделать, и продолжаю возвращаться к этому ответу - person Helsing; 03.06.2019

Чего ты действительно добиваешься? Если вам действительно нужно имя действия и имя контроллера... вы можете просто попросить

controller.controller_name

а также

controller.action_name

Это помогает, или вам действительно нужно разобрать строку, чтобы сделать это?

person mylescarrick    schedule 11.08.2010
comment
У меня есть авторизация на основе маршрута. По сути, в моей базе данных я подключаю контроллеры и действия, которые я хочу сделать доступными только для определенных пользователей, и рассматриваю их как разрешения. Я объединяю эти разрешения в роли и назначаю их своим пользователям. При посещении защищенной страницы предварительный фильтр определяет, разрешено ли пользователю находиться на этой странице. Это прекрасно работает (используя предложенные вами методы). Теперь мне нужно динамически отображать ссылку в зависимости от того, разрешено ли пользователю посещать страницу за ссылкой. У меня нет доступа к целевому контроллеру, только путь. - person ; 11.08.2010

Это то, что я в итоге сделал. Это уродливо, и должен быть лучший способ, но пока он работает. Это происходит в before_filter, чтобы я мог видеть, есть ли у пользователя доступ к контроллеру/действию, к которому он пытается получить доступ.

Я решил использовать авторизацию на основе маршрута, а не авторизацию на основе модели.

# Get method of current request
method = options[:method] ? options[:method] : 'get'

# Create a new request - hate this that is required
env = Rack::MockRequest.env_for(url, {:method => method})
request = ActionController::Request.new(env)

# For some reason, calling this fills in the controller / action information for the request
# just using recognize_path doesn't work correctly with resources...
ActionController::Routing::Routes.recognize(request)

Затем вы получаете доступ к контроллеру и действию с помощью request.params[:controller] и request.params[:action].

Во всем этом не было бы необходимости, если бы ActionController::Routing::Routes.recognize_path("/permissions/1") возвращал правильное действие.

person Community    schedule 08.10.2010