8

如何在创建设计用户时自定义 JSON 输出?

### User.rb ###
class User < ActiveRecord::Base
  devise :database_authenticatable,
         :registerable, ...
  ...
end

### Routes.rb ###
...
devise_for :users, :controllers => {:registrations => "registrations"}
...

我的用户表中有一些额外的字段是秘密的,但是当我通过 JSON 进行用户创建时,它们会在 JSON 响应中返回,如下所示:

$ curl -H "Content-Type: application/json" -d '{"user" : {"username":"someone","email":"someone@somewhere.com","password":"awesomepass"}}' -X POST http://localhost:3000/users.json

返回:

{"user":{"secret_field_1":"some value","secret_field_2":"some value","created_at":"2013-07-25T21:24:50-05:00","email":"someone@somewhere.com","first_name":null,"id":3226,"last_name":null,"updated_at":"2013-07-25T21:24:50-05:00","username":"someone"}}

我想隐藏那些秘密字段,但不知道如何自定义 JSON 响应。

我试过一个标准的 ActiveRecord 序列化器:

class UserSerializer < ActiveModel::Serializer
  attributes :id, :created_at, :updated_at, :email, :first_name, :last_name, :username
end

无济于事,我猜是因为设计。

4

5 回答 5

11

I just ran into the same issue. I haven't pinpointed exactly why but it looks like respond_with in Devise's SessionsController (tested on Devise 3.0 and active_model_serializers 0.8.1) doesn't trigger the ActiveModel::Serializer.

So I overrode respond_with in my controller:

class SessionsController < Devise::SessionsController

  def respond_with(resource, opts = {})
    render json: resource # Triggers the appropriate serializer
  end

end

It is, however, working in my RegistrationsController with respond_with. There I needed to do the following:

class RegistrationsController < Devise::RegistrationsController

  respond_to :json
end
于 2013-08-01T04:57:56.467 回答
3

我最近遇到了这个问题,重写respond_with并没有解决这个问题。我最终to_json像这样在 user.rb 中覆盖:

def to_json(arg)
  UserSerializer.new(self).to_json
end

不确定额外的 arg 是什么,但这似乎是其中一个设计 mixin 所必需的。

我正在使用以下内容:

  • 导轨 4.2.0
  • 设计 3.4.1
于 2015-01-25T20:19:11.933 回答
0

只是一个猜测,但听起来 rails 没有找到您的序列化程序并且正在使用to_json(). 你active_model_serializer()在你的模型中定义了吗?

于 2013-08-01T05:56:25.480 回答
0

我刚遇到同样的问题,下面是我的解决方法,很简单。

这些都传入active_model_serializers (0.9.5)

覆盖设计注册方法,并在您的自定义操作中:

def registration
  //Some process, and you get a @user when registration is successful.

  render :json => UserSerializer.new(@user)
end

如果您想将一些参数传递给您自定义的序列化器(例如令牌),您可以在您的操作中传递它:

render :json => UserSerializer.new(@user).as_json({auth_token: your_token})

在您的序列化程序中,只需使用:

class UserSerializer < ActiveModel::Serializer
  attributes :id, :name, :avatar_url, :auth_token

  def auth_token
    serialization_options[:auth_token]
  end
end
于 2016-05-27T08:39:23.570 回答
-1

根据您对该 JSON 所做的操作,您只需从序列化程序中删除不需要的属性。

例如 :

class UserSerializer < ActiveModel::Serializer
  attributes :id, :email, :username
end

我认为,就您而言,您只是想这样做。

但是您也可以在特定条件下包含一个属性:

class PostSerializer < ActiveModel::Serializer
  attributes :id, :title, :body, :author

  def include_author?
    current_user.admin?
  end
end

最后,您可以覆盖属性方法以返回您需要的哈希:

class PersonSerializer < ActiveModel::Serializer
  attributes :first_name, :last_name

  def attributes
    hash = super
    if current_user.admin?
      hash["ssn"] = object.ssn
      hash["secret"] = object.mothers_maiden_name
    end
    hash
  end
end

有关更多信息,请参阅README 。ActiveModel::Serializers

于 2013-07-31T10:51:26.830 回答