Ruby on Rails 3 - to_json 不包括所有属性

发布于 2024-11-27 09:00:14 字数 498 浏览 0 评论 0原文

我在我的模型对象上使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一个人练习一个人 2024-12-04 09:00:15

如果您像我一样来这里寻找 Rails 4,这里有一些信息会有所帮助。

正如艾伦·大卫·加西亚(Alan David Garcia)上面所说,Devise 会覆盖 serialized_hash。要强制覆盖,您可以执行以下操作,例如,在调用 Model#as_json 时返回除 password_digest 之外的所有属性。

def as_json(options = {})
  options[:force_except] ||= [:password_digest]
  super(options)
end

您可以在 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 except password_digest when calling Model#as_json.

def as_json(options = {})
  options[:force_except] ||= [:password_digest]
  super(options)
end

You can specify any desired model attributes to exclude in options[:force_except] instead of just :password_digest.

烟沫凡尘 2024-12-04 09:00:15

在你的模型类中包含这样的内容:

  attr_accessible :id, :email, :password, :password_confirmation, :remember_me

最初,id 未包含在 json 中,但在我将其添加到 attr_accessible 后,它起作用了!

include something like this in your model class:

  attr_accessible :id, :email, :password, :password_confirmation, :remember_me

Initially the id wasn't included in json but after I added it to attr_accessible it worked!!

朱染 2024-12-04 09:00:14

我没有检查过,但我相信 Devise 会为你做到这一点;它仅通过 attr_accessible 包含某些属性。

无论如何,解决这个问题的正确方法是重写 as_json 方法,如下所示:

def as_json(options = nil)
  {
    my_attr: my_attr,
    etc: etc
  }
end

它是一个简单的哈希,是在 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:

def as_json(options = nil)
  {
    my_attr: my_attr,
    etc: etc
  }
end

It's a simple hash and it's a really powerful method to generate JSON in AR, without messing with the to_json method.

感情洁癖 2024-12-04 09:00:14

正如 kain 所提到的,Devise 确实为您过滤了属性。
尽管如此,我宁愿只附加我需要的内容,而不是重写 Devise 的逻辑。

相反,我宁愿做

def as_json(options={})
  json_res = super options
  json_res['locked_at'] = self.locked_at
  json_res['confirmed_at'] = self.confirmed_at
end

或您的用户可能拥有您想要传递的任何其他属性

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

def as_json(options={})
  json_res = super options
  json_res['locked_at'] = self.locked_at
  json_res['confirmed_at'] = self.confirmed_at
end

or whatever other attributes your user might have that you want to pass

所谓喜欢 2024-12-04 09:00:14

默认情况下,Devise 会覆盖serialized_hash 方法以仅公开可访问的属性(因此,像encrypted_pa​​ssword 这样的内容默认情况下不会在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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文