新手问题 Grape + Serializer,如何在 JSON 输出中增加 current_user 这样的变量?

xlaok · 发布于 2015年10月14日 · 最后由 duanjs 回复于 2016年5月09日 · 991 次阅读
2898

比如一个新闻,需要增加current是否阅读过这个值,因为数据库中没有,需要在serializer中定义

def is_viewed
   current_user.is_viewed
end

这个 current_user 是定义在 grape 程序中的,一个个注入修改又太过麻烦,如何统一解决呢?

共收到 8 条回复
5597
onemagicant · #1 · 2015年10月14日

active_model_serializers 默认会将 current_user 方法传入

def is_viewed
   scope.is_viewed
end

如果你想将其他方法传入, https://github.com/rails-api/active_model_serializers/tree/0-9-2#customizing-scope

2898
xlaok · #2 · 2015年10月14日

#1楼 @onemagicant 我用的是 grape-active_model_serializers 官方文档中也给到了类似的例子,但是报错 undefined local variable or method `current_user' for # 你知道是怎么回事吗

2898
xlaok · #3 · 2015年10月14日

#1楼 @onemagicant

https://github.com/jrhe/grape-active_model_serializers/issues/22 也谈到了,我用 https://github.com/jrhe/grape-active_model_serializers/pull/24 的方法 遇到了和下面一样的问题 UserSerializer#current_user delegated to scope.current_user, but scope is nil

96
jimrokliu · #4 · 2015年10月14日

#2楼 @xlaok 可以打一个堆栈出来,看看调用栈是什么,如果在调用栈上有rack 的env,可以设置在env上。

1105
martin · #5 · 2015年10月15日

之前在0.9.x中有这样一个 feature,不知道是否合并到 master 了 (我们以前使用的时候没有)

Gemfile

gem 'active_model_serializers', branch: '0-9-stable'

可以传递任意参数在 controller

present your_object, current_user: current_user

然后在 serializers 中直接使用serialization_options就可以了

def fake_method
  current_user = serialization_options[:current_user]
end

然后你可以简单包装下,这样就可以在 serializers中直接使用了。

5597
onemagicant · #6 · 2015年10月15日

#3楼 @xlaok https://github.com/jrhe/grape-active_model_serializers/blob/master/lib%2Fgrape-active_model_serializers%2Fendpoint_extension.rb#L27

但是我还是建议你不要使用这样的插件, 可以直接使用active_model_serializers, 你的这个问题可以https://github.com/rails-api/active_model_serializers/blob/master/lib%2Factive_model%2Fserializer.rb#L148

可以直接出入参数的方式将 current_user 传入, 像 @martin 所说. 调用的方式就是 如: https://github.com/rails-api/active_model_serializers#using-a-serializer-without-render
ActiveModel::SerializableResource.new(@message, scope: current_user).serializable_hash

12662
duanjs · #7 · 2016年5月09日

在VideoAPI中这样传送参数:

 get '/:slug',serializer: VideoDetalSerializer do 
     slug = params[:slug]
      video = ::Video.find_by(slug:params[:slug])
      present video, type: 'video'
end

然后在VideoDetalSerializer里面这样获取serialization_options[:type],官方文档说能获取,但是我测试的时候一样获取不到

12662
duanjs · #8 · 2016年5月09日

@xlaok k @martinchu current_user 通过scope.current_user获取没问题,传其他参数的就有问题

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册