Ruby on Rails: url_for: back приводит к NoMethodError для back_url

Я пытаюсь использовать url_for (: back) для создания перенаправления, ведущего на предыдущую страницу после входа пользователя в систему.

У меня он работал успешно, когда пользователь просто переходит на страницу входа в систему самостоятельно. Однако, когда пользователь перенаправляется на страницу входа в систему из-за доступа к странице, требующей аутентификации пользователя, перенаправление отправляет пользователя обратно на страницу до того, к которому он попытался получить доступ с недостаточными разрешениями.

Я пытаюсь изменить действие контроллера входа в систему, чтобы правильно обрабатывать перенаправление. Я планирую использовать параметр строки запроса «перенаправление», когда происходит принудительное перенаправление. В контроллере, если этот параметр существует, используется этот URL-адрес; в противном случае используется url_for (: back), или, если это не работает (из-за отсутствия HTTP_REFERER), пользователь перенаправляется на домашнюю страницу сайта.

Вот фрагмент кода, который должен реализовать эту логику:

if params[:redirect]
  @url = params[:redirect]
else
  @url = url_for :back
  @url ||= url_for :controller => "home", :action => "index"
end

Я получаю следующую ошибку:

NoMethodError in UsersController#login

undefined method `back_url' for #

RAILS_ROOT: [obscured]
Application Trace | Framework Trace | Full Trace

vendor/rails/actionpack/lib/action_controller/polymorphic_routes.rb:112:in `__send__'
vendor/rails/actionpack/lib/action_controller/polymorphic_routes.rb:112:in `polymorphic_url'
vendor/rails/actionpack/lib/action_controller/base.rb:628:in `url_for'
app/controllers/users_controller.rb:16:in `login'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/rails.rb:76:in `process'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/rails.rb:74:in `synchronize'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/rails.rb:74:in `process'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:159:in `process_client'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `each'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `process_client'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `initialize'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `new'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `initialize'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `new'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:282:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:281:in `each'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:281:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:128:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/command.rb:212:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:281

vendor/rails/actionpack/lib/action_controller/polymorphic_routes.rb:112:in `__send__'
vendor/rails/actionpack/lib/action_controller/polymorphic_routes.rb:112:in `polymorphic_url'
vendor/rails/actionpack/lib/action_controller/base.rb:628:in `url_for'
vendor/rails/actionpack/lib/action_controller/base.rb:1256:in `send'
vendor/rails/actionpack/lib/action_controller/base.rb:1256:in `perform_action_without_filters'
vendor/rails/actionpack/lib/action_controller/filters.rb:617:in `call_filters'
vendor/rails/actionpack/lib/action_controller/filters.rb:610:in `perform_action_without_benchmark'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
vendor/rails/actionpack/lib/action_controller/rescue.rb:136:in `perform_action_without_caching'
vendor/rails/actionpack/lib/action_controller/caching/sql_cache.rb:13:in `perform_action'
vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
vendor/rails/activerecord/lib/active_record/query_cache.rb:8:in `cache'
vendor/rails/actionpack/lib/action_controller/caching/sql_cache.rb:12:in `perform_action'
vendor/rails/actionpack/lib/action_controller/base.rb:524:in `send'
vendor/rails/actionpack/lib/action_controller/base.rb:524:in `process_without_filters'
vendor/rails/actionpack/lib/action_controller/filters.rb:606:in `process_without_session_management_support'
vendor/rails/actionpack/lib/action_controller/session_management.rb:134:in `process'
vendor/rails/actionpack/lib/action_controller/base.rb:392:in `process'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:184:in `handle_request'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:112:in `dispatch_unlocked'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:125:in `dispatch'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:124:in `synchronize'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:124:in `dispatch'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:134:in `dispatch_cgi'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:41:in `dispatch'
vendor/rails/activesupport/lib/active_support/dependencies.rb:142:in `load_without_new_constant_marking'
vendor/rails/activesupport/lib/active_support/dependencies.rb:142:in `load'
vendor/rails/activesupport/lib/active_support/dependencies.rb:521:in `new_constants_in'
vendor/rails/activesupport/lib/active_support/dependencies.rb:142:in `load'
vendor/rails/railties/lib/commands/servers/mongrel.rb:64
/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
vendor/rails/activesupport/lib/active_support/dependencies.rb:153:in `require'
vendor/rails/activesupport/lib/active_support/dependencies.rb:521:in `new_constants_in'
vendor/rails/activesupport/lib/active_support/dependencies.rb:153:in `require'
vendor/rails/railties/lib/commands/server.rb:49
/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
script/server:3

vendor/rails/actionpack/lib/action_controller/polymorphic_routes.rb:112:in `__send__'
vendor/rails/actionpack/lib/action_controller/polymorphic_routes.rb:112:in `polymorphic_url'
vendor/rails/actionpack/lib/action_controller/base.rb:628:in `url_for'
app/controllers/users_controller.rb:16:in `login'
vendor/rails/actionpack/lib/action_controller/base.rb:1256:in `send'
vendor/rails/actionpack/lib/action_controller/base.rb:1256:in `perform_action_without_filters'
vendor/rails/actionpack/lib/action_controller/filters.rb:617:in `call_filters'
vendor/rails/actionpack/lib/action_controller/filters.rb:610:in `perform_action_without_benchmark'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
vendor/rails/actionpack/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
vendor/rails/actionpack/lib/action_controller/rescue.rb:136:in `perform_action_without_caching'
vendor/rails/actionpack/lib/action_controller/caching/sql_cache.rb:13:in `perform_action'
vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
vendor/rails/activerecord/lib/active_record/query_cache.rb:8:in `cache'
vendor/rails/actionpack/lib/action_controller/caching/sql_cache.rb:12:in `perform_action'
vendor/rails/actionpack/lib/action_controller/base.rb:524:in `send'
vendor/rails/actionpack/lib/action_controller/base.rb:524:in `process_without_filters'
vendor/rails/actionpack/lib/action_controller/filters.rb:606:in `process_without_session_management_support'
vendor/rails/actionpack/lib/action_controller/session_management.rb:134:in `process'
vendor/rails/actionpack/lib/action_controller/base.rb:392:in `process'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:184:in `handle_request'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:112:in `dispatch_unlocked'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:125:in `dispatch'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:124:in `synchronize'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:124:in `dispatch'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:134:in `dispatch_cgi'
vendor/rails/actionpack/lib/action_controller/dispatcher.rb:41:in `dispatch'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/rails.rb:76:in `process'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/rails.rb:74:in `synchronize'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/rails.rb:74:in `process'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:159:in `process_client'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `each'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `process_client'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `initialize'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `new'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `initialize'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `new'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:282:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:281:in `each'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:281:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:128:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/command.rb:212:in `run'
/var/lib/gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:281
vendor/rails/activesupport/lib/active_support/dependencies.rb:142:in `load_without_new_constant_marking'
vendor/rails/activesupport/lib/active_support/dependencies.rb:142:in `load'
vendor/rails/activesupport/lib/active_support/dependencies.rb:521:in `new_constants_in'
vendor/rails/activesupport/lib/active_support/dependencies.rb:142:in `load'
vendor/rails/railties/lib/commands/servers/mongrel.rb:64
/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
vendor/rails/activesupport/lib/active_support/dependencies.rb:153:in `require'
vendor/rails/activesupport/lib/active_support/dependencies.rb:521:in `new_constants_in'
vendor/rails/activesupport/lib/active_support/dependencies.rb:153:in `require'
vendor/rails/railties/lib/commands/server.rb:49
/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
script/server:3

Request

Parameters:

None

Show session dump

--- 
:user: 
:csrf_id: 2927cca61bbbe97218362b5bcdb74c0f
flash: !map:ActionController::Flash::FlashHash {}


Response

Headers:

{"Content-Type"=>"",
 "cookie"=>[],
 "Cache-Control"=>"no-cache"}

Имейте в виду, что у меня это работало раньше - url_for (: back) знал, как работать правильно, прежде чем я добавил эту логику.

Заранее спасибо за любые идеи!


person Platinum Azure    schedule 26.05.2010    source источник


Ответы (2)


Вы пытаетесь использовать вспомогательный метод представления в своем контроллере. Ожидаемое поведение находится в ActionView :: Helpers :: UrlHelper, но вызываемый вами метод находится в ActionController :: Base. К сожалению, оба метода названы одинаково и имеют очень похожие функции, но не совсем одинаковые.

Для быстрого исправления ActionController :: Base устанавливает переменную @template, которая имеет доступ ко всем помощникам ActionView. Попробуйте вызвать url_for из этого объекта, например:

if params[:redirect]
  @url = params[:redirect]
else
  @url = @template.url_for :back
  @url ||= url_for :controller => "home", :action => "index"
end

Однако я не уверен, что это «правильный» способ сделать это. Если бы разработчики рельсов хотели, чтобы мы добровольно использовали переменную @template, они бы больше ее рекламировали.

Другой способ получить URL-адрес исходного реферера (искомого: back) - использовать метод request:

if params[:redirect]
  @url = params[:redirect]
else
  @url = request.env["HTTP_REFERER"]
  @url ||= url_for :controller => "home", :action => "index"
end
person irkenInvader    schedule 26.05.2010
comment
Это работает. Теперь у меня есть ошибка в представлении, также с url_for, но то, что вы сказали, устранило эту ошибку. Спасибо :-) (+1) - person Platinum Azure; 26.05.2010

В моем случае иногда: back указывает на то же место, которое я хочу покинуть, поэтому возникает цикл. Мое решение было: Метод в application_controller

def new_loc
  url = request.referer.to_s
  url == "" || url == request.url ? root_path : url
end

и в вашем контроллере

@url = params[:redirect] ? params[:redirect] : new_loc

Или в моем случае

redirect_to new_loc

Вот и все. Я на Rails 5

person Fer Padron    schedule 23.07.2017