Rails.application.routes.recognize_path,设计经过验证的路由

时间:2013-03-17 11:35:40

标签: ruby-on-rails ruby-on-rails-3 devise

我有一个支持设备的路线:

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

和控制器:

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

提出:

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

我需要根据request.referer控制器名称在destroy动作中呈现不同的模板。如何为此类URL获取“经过身份验证的”控制器/操作名称?

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

您可以使用: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

然后用

打电话
RouteRecognizer.is_route?('http://whatever')

答案 2 :(得分:0)

似乎使用Rails.application.routes.recognize_path对自定义路由约束(如设计#authenticated方法)效果不佳。

请参阅https://github.com/plataformatec/devise/issues/3747

  

recogn_path不会像需要请求相关对象的约束一样工作(比如Devise期望在请求env Hash中的warden实例)。如果你在控制器代码中执行此操作,则可以将warden对象从request.env传递给recogn_path调用,或者尝试将对象传递给识别路径的类。

     

另一方面,由于recogn_path不是一个记录在案的公共API,我强烈建议您不要使用它并在应用程序中保存params Hash而不是原始URL。

您的问题的一个解决方案可能是在会话中保存控制器/操作名称,并在需要时访问它们。