Rails Devise current_user是否在匹配中未定义?高级路线约束

时间:2012-09-25 18:35:39

标签: ruby-on-rails devise

当我尝试在匹配?约束中使用current_user时出现错误NameError (undefined local variable or method "current_user" for #<APIRouter:0x007ffd54a81f98>):。我希望将某个虚拟用户路由到一组控制器,并将其他用户路由到另一组控制器。但是,当我尝试使用current_user时,我收到一个错误。

  • 设计(2.0.4)
  • rails(3.2.2)

我的匹配约束在APIRouter类中定义:

class APIRouter
  def matches? request
    @use_rm_app = ENV["USE_RM_APP"] == "true" || (current_user && current_user.is_test)
  end
end

关于如何在比赛中使用当前用户的任何想法? Rails guide中定义的约束。

routes.rb文件中的部分:

#  Route to the rm_app controller if APIRouter says we should, otherwise use the real backend controllers.
match '/api/v1/*path', :controller => 'api/v1', 
  :action => 'handle_create_request', 
  :via => :post, :constraints => APIRouter.new

更新:感谢ksol。 尝试3工作。使用request.env["warden"].user(:user)

获取用户

解决方案是修改APIRouter

  def matches? request
    user = request.env["warden"].user(:user)
    (user && user.is_test) || ENV["USE_RM_APP"] == "true"
  end

3 个答案:

答案 0 :(得分:11)

current_user仅适用于您的控制器和视图。有多种方法可以实现您的想法,更容易将其作为参数提供给您的方法。

修改

如果在路由器中可以访问current_user,则可以通过constraints: APIRouter.new(current_user)将其传递给约束类。然后,您需要定义APIRouter#initialize并将current_user存储在可以在matches?中使用的实例var中。

编辑2

我记得设计允许你在路由器中执行此操作:

authenticated :user do
  root :to => "main#dashboard"
end

我不知道如何确保user.is_test

编辑3

最后一次尝试。如果用户经过身份验证,request.env["warden"].user(:user)应该会为您提供。

答案 1 :(得分:6)

在ksol的帖子的基础上,您可以通过将块传递给经过身份验证来确保user.is_test:

authenticated :user, lambda {|u| u.is_test } do
    // route stuff here
end

这假设u.is_test返回一个布尔值。

答案 2 :(得分:0)

请记住添加diff:和两个root一样,否则会通过错误

authenticated :user do
  root :to => "main#dashboard", :as => :foo
end

root :to => "main#landing_page"