【问题标题】:Active Model Serializer - How do I include an attribute conditionally? RailsActive Model Serializer - 如何有条件地包含属性?导轨
【发布时间】:2015-11-23 19:09:49
【问题描述】:

我在我的 Rails 4 API 中使用 Active Model Serializers,我一直在试图弄清楚当用户在 @ 登录时如何在我的 JSON 响应中包含 auth_token 属性 987654323@。我阅读了AMS documentation 并尝试了大多数看似解决方案,但都没有奏效。

需要指出的几点:

  • :auth_token 不在UserSerializer 的属性列表中。
  • 由于auth_token 是特定于控制器的,我无法在UserSerializer 中执行条件逻辑,除非有办法确定在串行器中调用了哪个控制器。所以没有def include_auth_token? ... end

我已经尝试过的一些事情:

class Api::V1::SessionsController < ApplicationController
    if user = User.authenticate(params[:session][:email], params[:session][:password])
        if user.active
          user.generate_auth_token   #=> Custom method
          user.save

          # Tried using the meta param
          render :json => user, :meta => {:auth_token => user.auth_token}

          # Tried using the include param both with 'auth_token' and 'user.auth_token'
          render :json => user, include: 'user.auth_token'
        end
    end
end

理想情况下,我希望能够使用类似于render :json =&gt; user, :include =&gt; :auth_token 的东西来另外包含UserSerializer 中尚未定义的属性。

使用 AMS 有条件地包含来自控制器的属性的正确方法是什么?

【问题讨论】:

    标签: ruby-on-rails ruby json api rest


    【解决方案1】:

    阅读文档后,include 似乎仅在 v0.10.0 版本中可用。 v0.9 中的正确文档是:https://github.com/rails-api/active_model_serializers/tree/v0.9.0#attributes。 我以前使用过filter 方法,这样的方法应该可以解决问题:

    class Api::V1::SessionsController < ApplicationController
      if user = User.authenticate(params[:session][:email], params[:session][:password])
        if user.active
          user.generate_auth_token
          user.save
    
          render :json => user, :meta => {:auth_token => user.auth_token}
        end
      end
    end
    
    
    
    class UserSerializer < ActiveModel::Serializer
      attributes :id, :name, :auth_token
    
      def filter(keys)
       if meta && meta['auth_token']
         keys
       else
         keys - [:auth_token]
       end
      end
    end
    

    【讨论】:

      【解决方案2】:

      您无需依赖render :json =&gt; user 调用将用户序列化为 JSON 有效负载,而是可以自己制作有效负载并控制包含的内容和不包含的内容。

      user_payload = user.as_json
      
      user_payload.merge!(:auth_token => user.auth_token) if include_auth_token?
      
      render :json => user_payload
      

      as_json 方法返回表示模型的哈希值。然后,您可以在 JSON 序列化程序将其转换为正确的 JSON 之前修改此哈希。

      【讨论】:

      • 这确实有点作用,但没有达到我想要的结果。使用此方法返回所有属性并在我的render :json 调用中使用:exclude 选项(奇怪的是)没有删除属性。不过,我感谢您的帮助。
      • 如果:exclude选项有什么奇怪的地方,你可以直接在最后一个选项中修改hash,比如:render :json =&gt; user_payload.except(:some, :keys, :to, :exclude)
      猜你喜欢
      • 1970-01-01
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-05
      • 2014-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多