如何在创建设备用户时自定义JSON输出?
### User.rb ###
class User < ActiveRecord::Base
devise :database_authenticatable,
:registerable, ...
...
end
### Routes.rb ###
...
devise_for :users, :controllers => {:registrations => "registrations"}
...
我的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
返回:
{"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
无济于事,我因为设计而猜测。
答案 0 :(得分:9)
我刚遇到同样的问题。我没有确切地指出原因,但在Devise的SessionsController中看起来像respond_with
(在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
然而,它在我的RegistrationsController中使用respond_with
。我需要做以下事情:
class RegistrationsController < Devise::RegistrationsController
respond_to :json
end
答案 1 :(得分:3)
我最近碰到了这个问题,并且覆盖respond_with
没有解决问题。我最终在user.rb中覆盖了to_json
,如下所示:
def to_json(arg)
UserSerializer.new(self).to_json
end
不确定额外的arg是什么,但其中一个设计mixin似乎需要它。
我正在使用以下内容:
答案 2 :(得分:0)
只是一个猜测,但听起来像rails没有找到你的序列化器并使用to_json()
。您是否在模型中定义了active_model_serializer()
?
答案 3 :(得分: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
如果您想将一些参数传递给自定义的Serializer(例如令牌),您可以在操作中传递它:
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
答案 4 :(得分:-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
最后,您可以覆盖attributes方法以返回所需的哈希:
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
有关更多信息,请参阅ActiveModel::Serializers
的{{3}}。