这个lambda函数如何传递给Devise的经过身份验证的方法?

时间:2015-03-18 21:28:47

标签: ruby-on-rails ruby devise

this问题中,@ user2205763建议使用lambda函数:

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

我认为它以某种方式将:user转变为实际的Devise User对象(u),但它是如何做到的 - 它实际上在做什么?< / p>

1 个答案:

答案 0 :(得分:3)

Rails允许在路由定义中使用constraints基于一组规则约束路由。请参阅API文档中的Dynamic request matching示例。

Devise正在其authenticated方法中使用它。其来源是here

authenticated方法如下所示:

def authenticated(scope=nil, block=nil)
  constraints_for(:authenticate?, scope, block) do
    yield
  end
end

并且正在调用constraints_for

def constraints_for(method_to_apply, scope=nil, block=nil)
  constraint = lambda do |request|
    request.env['warden'].send(method_to_apply, scope: scope) &&
      (block.nil? || block.call(request.env["warden"].user(scope)))
  end

  constraints(constraint) do
    yield
  end
end 

因此scope:usermethod_to_apply:authenticate?request.env["warden"]为对象injected into the environment by Warden,可让您检查身份验证。< / p>

这意味着constraint = ...正在创建一个调用authenticate?的lambda,然后调用您的块,例如将|u| u.is_test设置为u的结果request.env["warden"].user(即调用authenticate?后的当前用户)

然后将lambda作为匹配到constraints的动态请求传递,这反过来会产生// route stuff here所在的块!