Altering fields included in Rails' default JSON/XML serialization
I'm writing a web service to return a user's details. In the controller, I simply 开发者_运维知识库render :xml => user and return
. However, not all of the fields of my User model are being returned, and I don't see anything in my model that would indicate which fields to include or exclude.
Model:
class User < ActiveRecord::Base
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me, :first_name, :last_name
end
Example:
irb(main):003:0> @user = User.find(3)
=> #<User id: 3, email: "me@me.me", encrypted_password: <redacted>, reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 11, current_sign_in_at: "2011-08-24 22:50:44", last_sign_in_at: "2011-08-24 06:18:41", current_sign_in_ip: "1.2.3.4", last_sign_in_ip: "1.2.3.4", created_at: "2011-08-23 17:09:28", updated_at: "2011-08-26 04:01:01", controller: false, admin: false, chargify_customer_id: 1234, chargify_subscription_id: 1234, first_name: "Me", last_name: "Me", chargify_subscription_state: "active">
What my render
is currently returning for that same user:
<?xml version="1.0" encoding="UTF-8"?>
<user>
<last-name>Me</last-name>
<email>me@me.me</email>
<first-name>Me</first-name>
</user>
At a minimum, I need to include the id
field; overall, I'd like to understand better how you control what gets included and what doesn't.
Serialization happens in the as_json/as_xml
methods. By default these methods serialize all of your models attributes into json/xml. However, devise hides certain attributes generated by its ActiveRecord extensions. That's why you don't get the password fields for example.
You can control which attributes get included in your xml by overriding the to_xml method in your user model.
def as_xml(options = {})
default_options = {
:only => [:id, :first_name, :last_name, :email]
}
xml_options = options.blank? ? default_options : options
super xml_options
end
You can also include custom methods of your model.
def as_xml(options = {})
default_options = {
:only => [:id, :first_name, :last_name, :email],
:methods => [:some_custom_method]
}
xml_options = options.blank? ? default_options : options
super xml_options
end
You can read more about serialization here: http://api.rubyonrails.org/classes/ActiveRecord/Serialization.html
精彩评论