在创建用户帐户时自定义设计用户JSON响应

jos*_*ine 7 activerecord json ruby-on-rails devise

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

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

### Routes.rb ###
...
devise_for :users, :controllers => {:registrations => "registrations"}
...
Run Code Online (Sandbox Code Playgroud)

我的User表中有一些额外的字段是秘密的,但当我通过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
Run Code Online (Sandbox Code Playgroud)

返回:

{"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"}}
Run Code Online (Sandbox Code Playgroud)

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

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

class UserSerializer < ActiveModel::Serializer
  attributes :id, :created_at, :updated_at, :email, :first_name, :last_name, :username
end
Run Code Online (Sandbox Code Playgroud)

没有用,我猜是因为Devise.

mat*_*wer 11

我刚遇到同样的问题.我没有确切地指出为什么,但它看起来像respond_with在Devise的SessionsController(在Devise 3.0和active_model_serializers 0.8.1上测试)不会触发ActiveModel::Serializer.

所以我respond_with在我的控制器中覆盖了:

class SessionsController < Devise::SessionsController

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

end
Run Code Online (Sandbox Code Playgroud)

但是,它在我的RegistrationsController中工作respond_with.我需要做以下事情:

class RegistrationsController < Devise::RegistrationsController

  respond_to :json
end
Run Code Online (Sandbox Code Playgroud)


Sim*_*mon -1

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

例如 :

class UserSerializer < ActiveModel::Serializer
  attributes :id, :email, :username
end
Run Code Online (Sandbox Code Playgroud)

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

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

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

  def include_author?
    current_user.admin?
  end
end
Run Code Online (Sandbox Code Playgroud)

最后,您可以重写属性方法以返回所需的哈希值:

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
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅READMEActiveModel::Serializers