简体   繁体   English

活动 Model 序列化程序 - 如何有条件地包含属性? 导轨

[英]Active Model Serializer - How do I include an attribute conditionally? Rails

I am using Active Model Serializers with my Rails 4 API, and I have been trying to figure out how to include the auth_token attribute in my JSON response only when the user logs in at sessions#create .我在我的 Rails 4 API 中使用 Active Model 序列化程序,并且我一直在尝试弄清楚如何当用户在sessions#create登录时才在我的 JSON 响应中包含auth_token属性。 I read the AMS documentation and tried most of the seeming solutions but none worked.我阅读了AMS 文档并尝试了大多数看似可行的解决方案,但都没有奏效。

Couple things to point out:需要指出的几件事:

  • :auth_token is not in the UserSerializer 's attributes list. :auth_token不在UserSerializer的属性列表中。
  • Since the auth_token is controller-specific, I can't do the conditional logic in the UserSerializer unless there is a way to determine what controller was called in the Serializer.由于auth_token是特定于控制器的,我无法在UserSerializer中执行条件逻辑,除非有一种方法可以确定在序列化程序中调用了什么 controller。 So no def include_auth_token? ... end所以没有def include_auth_token? ... end def include_auth_token? ... end . def include_auth_token? ... end

Some of the things I've tried already:我已经尝试过的一些事情:

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

Ideally, I would like to be able to use something along the lines of render:json => user, :include =>:auth_token to additionally include attributes not already defined in the UserSerializer .理想情况下,我希望能够使用类似render:json => user, :include =>:auth_token的东西来另外包含尚未在UserSerializer中定义的属性。

What is the proper way to conditionally include attributes from the controller with AMS?使用 AMS 有条件地包含来自 controller 的属性的正确方法是什么?

After reading the documentation, looks like the include will be available only in the v0.10.0 version. 阅读文档后,似乎include仅在v0.10.0版本中可用。 The correct docs from v0.9 are these: https://github.com/rails-api/active_model_serializers/tree/v0.9.0#attributes . 来自v0.9的正确文档是: https : //github.com/rails-api/active_model_serializers/tree/v0.9.0#attributes I've used the filter method before, something like this should do the trick: 我以前使用过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

Instead of relying on the render :json => user call to serialize the user to a JSON payload, you can craft the payload yourself and have control over what is and what is not included. 无需依靠render :json => user调用将用户序列化为JSON有效负载,您可以自己制作有效负载并控制包含的内容和不包含的内容。

user_payload = user.as_json

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

render :json => user_payload

The as_json method Returns a hash representing the model. as_json方法返回表示模型的哈希。 You can then modify this hash before the JSON serializer turns it into proper JSON. 然后,您可以在JSON序列化器将其转换为正确的JSON之前修改此哈希。

You can define attributes conditionally.您可以有条件地定义属性。 See here .这里

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

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