【问题标题】:Access doorkeeper_token (or current_user) in Active_model_serializers在 Active_model_serializers 中访问 doorkeeper_token(或 current_user)
【发布时间】:2013-12-03 19:25:26
【问题描述】:

我正在使用 RocketPants 制作 Rails API。对于 JSON 序列化,我使用 active_model_serializers,对于 OAuth - Doorkeeper

问题在于访问class UserSerializer < ActiveModel::Serializer 中的current_user 辅助方法。错误:

NameError (undefined local variable or method `request' for #<UserSerializer:0xb5892118>)

current_user helper 使用这个sn-p:

User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token

doorkeeper_token 是:

def doorkeeper_token
    methods = Doorkeeper.configuration.access_token_methods
    @token ||= OAuth::Token.authenticate request, *methods
end

所以我发现,Serializer 中没有可访问的 request 对象。我怎样才能使它可访问?还是应该有其他方式来实现current_user

提前致谢

【问题讨论】:

标签: ruby-on-rails active-model-serializers doorkeeper


【解决方案1】:

好的,所以正确的答案是使用scope 对象,包含在active-model-serializers 中。但是出现了一些问题: 如果我只是尝试在Serializer 中访问scope - 它是nil。我尝试通过serialization_scope :current_user 直接定义它并得到no method error,因为没有包含这种方法... 然后我包含了所需的模块:

class Api::V1::BaseController < RocketPants::Base
    include ActionController::Serialization
    ............

然后出现了奇怪的行为:它现在抱怨can't use 'merge' on Nil。深入研究 gem 的代码,我发现了函数

def default_serializer_options
  {
    :url_options => url_options,
    :root        => false
  }
end

,它在ActionController::Serialization 中被覆盖并且在那里是空函数,所以这就是我得到nil 的地方。

我不得不更改该函数以返回 super - 现在它没有抱怨错误,但仍然有 nil 而不是 scope。我设法通过在default_serializer_options 中包含:scope =&gt; serialization_scope 来修复这个问题。现在我可以按预期访问scope 对象了。

仍然不知道,为什么它需要奇怪的补丁这么长的路径,而我无法谷歌任何这样的案例。

拜托,如果有人可以帮我解决这个问题,请执行 =)

【讨论】:

  • 没有按预期工作的唯一原因是 RocketPants 没有传递 scope 对象。您是如何在 Rails 项目中安全地覆盖 ActionController::Serialization 的?我想使用您的解决方法。
  • @RobSobers 哦,天哪,经过这么长时间,这是一个疯狂的问题。我很久以前就用过c++了,但是我可以尝试找到我遇到这个问题的项目的源代码,然后把它交给你。
  • 谢谢@morodeer!我为此苦苦挣扎了几个小时,但仍然无法将 scope 变量设为非零。我现在有一个非常尴尬的解决方法,它不使用序列化程序,所以如果你找不到它,不用担心。能得到补丁就好了。
  • @RobSobers,看起来我在停止使用它之前还没有提交该项目的最后更改。也许我的 [博客] (morodeercoding.blogspot.ru/2013/12/…) 中的类似帖子可以提供更多帮助。这是我能提供的最大帮助。
【解决方案2】:

老实说,我从来没有真正使用过这些东西,但是从查看代码和文档来看,ActiveModel::Serializer 似乎使控制器可以使用current_user,但它是通过序列化程序的scope 属性来实现的.因此,在序列化程序中,如果您需要检查 current_user 是否为管理员,例如,您可以这样做:

if scope.is_admin?
  #your code here
end

【讨论】:

  • 不知何故 scope 在我的情况下是零。仍然找不到如何将它与 Doorkeeper 和 RocketPants 一起使用
猜你喜欢
  • 2012-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-15
  • 1970-01-01
  • 1970-01-01
  • 2013-09-04
相关资源
最近更新 更多