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!!
精彩评论