我在我的模型对象上使用to_json
方法,我做了类似的事情:
user = User.find(1)
当我执行user.to_json
时,会丢失许多属性,包括编码的JSON字符串中的user.id
。看来我从User模型添加为attr_accessible的所有属性都存在,但没有其他属性。也许这就是to_json正在做的事情,但我认为将id
添加到attr_accessible是不行的。
解决这个问题的正确方法是什么?
更新
这看起来是Devise的一个特定问题。如果我从user.rb注释掉以下内容,一切都按预期工作:
devise :rememberable, :trackable, :token_authenticatable, :omniauthable
答案 0 :(得分:5)
我没有检查,但我相信Devise会为你做这件事;它只包含某些属性,通过attr_accessible。
在任何情况下,解决此问题的正确方法是覆盖as_json
方法,如下所示:
def as_json(options = nil)
{
my_attr: my_attr,
etc: etc
}
end
这是一个简单的哈希,它是一种非常强大的方法,可以在AR中生成JSON,而不会弄乱to_json
方法。
答案 1 :(得分:2)
默认情况下,Devise会覆盖serializable_hash方法以仅公开可访问的属性(因此,像encrypted_password这样的东西在API上默认不会被序列化)。
您可以尝试覆盖此方法并将auth_token添加到哈希中,如下所示:
def serializable_hash(options = nil) super(options).merge(" auth_token" => auth_token) 端
答案 2 :(得分:2)
正如凯恩所提到的,设计确实为你过滤了属性。 然而,我宁愿只是追加我需要的东西而不是覆盖Devise的逻辑。
相反,我宁愿做
def as_json(options={})
json_res = super options
json_res['locked_at'] = self.locked_at
json_res['confirmed_at'] = self.confirmed_at
end
或您的用户可能要传递的任何其他属性
答案 3 :(得分:2)
如果你来这里寻找Rails 4,就像我一样,这里有一些有用的信息。
正如艾伦大卫加西亚上面所说,Devise凌驾于serializable_hash
。要强制覆盖,您可以执行以下操作,例如,在调用password_digest
时返回除Model#as_json
之外的所有属性。
def as_json(options = {})
options[:force_except] ||= [:password_digest]
super(options)
end
您可以在options[:force_except]
中指定要排除的任何所需模型属性,而不仅仅是:password_digest
。
答案 4 :(得分:0)
在您的模型类中包含类似的内容:
attr_accessible :id, :email, :password, :password_confirmation, :remember_me
最初这个id没有包含在json中,但是在我将它添加到attr_accessible之后它才有效!!