简体   繁体   中英

Rails.application.routes.recognize_path with devise authenticated route

I have a devise enabled route as:

#config/routes.rb
authenticated :user {
  root :to => 'home#signed_in'
}
root :to => 'home#index

and controller:

#app/controllers/home_controller.rb
class HomeController < ApplicationController
  def signed_in
    Rails.application.routes.recognize_path '/'
  end
end

which raises:

NoMethodError: undefined method `authenticate?' for nil:NilClass
...lib/devise/rails/routes.rb:286:in `block in authenticated'

I need such thing to render different templates in destroy action based on request.referer controller name. How can get 'authenticated' controller/action name for such URL?

  authenticated :user do
    root :to => 'home#signed_in'
  end

  unauthenticated :user do
    root :to => 'home#index'
  end

You can use this: https://gist.github.com/NullVoxPopuli/8c8af217b7404336c72a

class RouteRecognizer
  include Singleton

  ROUTE_LIST = Rails.application.routes.routes.collect{|r| r.path.spec.to_s}
  REGEX_ROUT_LIST = ROUTE_LIST.map{|r|
    Regexp.new(r.gsub(/\:(.*)id/, "(\d+)").gsub("(.:format)", ""))
  }

  def self.is_route?(path)
    REGEX_ROUT_LIST.each do |regex|
      return true if !!(path =~ regex)
    end
    false
 end
end

and then call with

RouteRecognizer.is_route?('http://whatever')

It seems using Rails.application.routes.recognize_path does not work well with custom routes constraints like devise #authenticated method.

See https://github.com/plataformatec/devise/issues/3747

recognize_path won't work as is with constraints that require request related objects (like the warden instance that Devise expects to be in the request env Hash). If you are doing this inside a controller code you might be able to pass the warden object from request.env to the recognize_path call, or try to pass down the object down the the class that is recognizing the path.

In the other hand, as recognize_path isn't a documented public API, I strongly suggest you to not use it and save pieces of the params Hash instead of the raw URL on your application.

One solution to your problem could be to save the controller/action names in session and access them when you need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM