开发者

Ruby on Rails 3 - to_json not including all attributes

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


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.


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


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


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.


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!!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜