Ruby on Rails 3 - to_json 不包括所有属性
我在我的模型对象上使用 to_json
方法,该方法是通过执行以下操作创建的:
user = User.find(1)
当我执行 user.to_json 时
,许多属性丢失,包括编码 JSON 字符串中的 user.id
。看来我从用户模型添加为 attr_accessible 的所有属性都在那里,但其他属性都没有。也许这就是 to_json 正在做的事情,但我认为将 id 添加到 attr_accessible 是不行的。
解决这个问题的正确方法是什么?
更新
这看起来是 Devise 的一个特定问题。如果我从 user.rb 中注释掉以下内容,一切都会按预期工作:
devise :rememberable, :trackable, :token_authenticatable, :omniauthable
I'm using the to_json
method on my model object that I created by doing something like:
user = User.find(1)
When I do user.to_json
, a lot of attributes are missing, including user.id
from the encoded JSON string. It appears that all of the attributes that I've added as attr_accessible from the User model are there, but none of the others. Perhaps that is what to_json is doing, but I think that adding id
to attr_accessible is a no go.
What is the right way of solving this problem?
UPDATE
This looks to be a specific issue with Devise. If I comment out the following from user.rb, everything works as expected:
devise :rememberable, :trackable, :token_authenticatable, :omniauthable
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您像我一样来这里寻找 Rails 4,这里有一些信息会有所帮助。
正如艾伦·大卫·加西亚(Alan David Garcia)上面所说,Devise 会覆盖
serialized_hash
。要强制覆盖,您可以执行以下操作,例如,在调用Model#as_json
时返回除password_digest
之外的所有属性。您可以在
options[:force_except]
中指定要排除的任何所需模型属性,而不仅仅是:password_digest
。If you came here looking for Rails 4, like I did, here's some information that will help.
As Alan David Garcia said above, Devise overrides
serializable_hash
. To force an override, you could do the following, for example, to return all attributes exceptpassword_digest
when callingModel#as_json
.You can specify any desired model attributes to exclude in
options[:force_except]
instead of just:password_digest
.在你的模型类中包含这样的内容:
最初,id 未包含在 json 中,但在我将其添加到 attr_accessible 后,它起作用了!
include something like this in your model class:
Initially the id wasn't included in json but after I added it to attr_accessible it worked!!
我没有检查过,但我相信 Devise 会为你做到这一点;它仅通过 attr_accessible 包含某些属性。
无论如何,解决这个问题的正确方法是重写
as_json
方法,如下所示:它是一个简单的哈希,是在 AR 中生成 JSON 的非常强大的方法,而不会弄乱
to_json< /代码> 方法。
I haven't checked but I believe Devise does that for you; it includes only certain attributes via attr_accessible.
In any case the right way to solve this is to override the
as_json
method like so:It's a simple hash and it's a really powerful method to generate JSON in AR, without messing with the
to_json
method.正如 kain 所提到的,Devise 确实为您过滤了属性。
尽管如此,我宁愿只附加我需要的内容,而不是重写 Devise 的逻辑。
相反,我宁愿做
或您的用户可能拥有您想要传递的任何其他属性
Devise indeed filters the attributes for you, as mentioned by kain.
Nevertheless, I'd rather just append exactly what I need to instead of overriding Devise's logic.
Instead, I'd rather do
or whatever other attributes your user might have that you want to pass
默认情况下,Devise 会覆盖serialized_hash 方法以仅公开可访问的属性(因此,像encrypted_password 这样的内容默认情况下不会在API 上序列化)。
您可以尝试覆盖此方法并将 auth_token 添加到哈希中,如下所示:
def serialized_hash(options = nil)
super(options).merge("auth_token" => auth_token)
结尾
By default Devise overrides the serializable_hash method to expose only accessible attributes (so things like the encrypted_password doesn't get serialized by default on APIs).
You could try to override this method and add the auth_token to the hash, something like this:
def serializable_hash(options = nil)
super(options).merge("auth_token" => auth_token)
end