简体   繁体   English

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

[英]Rails Devise current_user is undefined in a matches? advanced route constraint

I get an error NameError (undefined local variable or method "current_user" for #<APIRouter:0x007ffd54a81f98>): when I try to use current_user in a matches? 我得到一个错误NameError (undefined local variable or method "current_user" for #<APIRouter:0x007ffd54a81f98>):当我尝试在匹配中使用current_user时 constraint. 约束。 I want certain dummy user to be routed to one set of controllers and other users to be routed to another set of controllers. 我希望将某个虚拟用户路由到一组控制器,并将其他用户路由到另一组控制器。 However, when I try to use current_user I get an error. 但是,当我尝试使用current_user时,我收到一个错误。

  • devise (2.0.4) 设计(2.0.4)
  • rails (3.2.2) 铁轨(3.2.2)

My matches constraint is defined in the APIRouter Class: 我的匹配约束在APIRouter类中定义:

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

Any ideas as to how I can use current user in the matches? 关于我如何在比赛中使用当前用户的任何想法? constraint as defined in the Rails guide . Rails指南中定义的约束。

Section from the routes.rb file: 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

UPDATE: Solved thanks to ksol. 更新:解决了ksol。 Attempt 3 works. 尝试3工作。 Get user using request.env["warden"].user(:user) 使用request.env["warden"].user(:user)获取用户

Solution is to modify the APIRouter 解决方案是修改APIRouter

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

current_user is only available in your controllers and views. current_user仅在您的控制器和视图中可用。 There is more than one way to achieve what you want, the easier being supplying it as a parameter to your method. 有多种方法可以实现您的需求,将其作为参数提供给您的方法更容易。

EDIT 编辑

if current_user if accessible in the router, you can pass it to your constraints class by doing constraints: APIRouter.new(current_user) . 如果在路由器中可以访问current_user则可以通过约束将其传递给约束类constraints: APIRouter.new(current_user) Then you need to define APIRouter#initialize and store the current_user in an instance var that you can use in matches? 那么你需要定义APIRouter#initialize并将current_user存储在一个可以在matches?使用的实例var matches? .

EDIT 2 编辑2

I just remembered devise allows you to do this in your router : 我记得devise允许你在路由器中执行此操作:

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

I don't know how to ensure that user.is_test though. 我不知道如何确保user.is_test

EDIT 3 编辑3

Last attempt. 最后一次尝试。 request.env["warden"].user(:user) should give you a user if one is authenticated. request.env["warden"].user(:user)应该为用户提供经过身份验证的用户。

Building on ksol's post, you can ensure user.is_test by passing a block to authenticated: 在ksol的帖子的基础上,您可以通过将块传递给经过身份验证来确保user.is_test:

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

This is assuming that u.is_test returns a Boolean value. 这假设u.is_test返回一个布尔值。

Just remember to add diff :as for both root otherwise it will through error 只记得添加diff:和两个root一样,否则会出错

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

root :to => "main#landing_page"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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