Rails has a very handy ‘respond_to’ feature to render your pages in different formats :
respond_to do |format|
format.json { render :json => @user }
format.xml { render :xml => @user }
format.html
end
However, by default it outputs every field in the model, which exposes some data (encrypted-password and password-salt) that I’d rather keep to myself :
<user>
<encrypted-password>$2a$10$a2K.PXEXpgpWH6MMLD/AFe84mjB4u3ZNf4MYTPten42LkPpjd.wZm</encrypted-password>
<created-at type="datetime">2010-10-02T00:12:43Z</created-at>
<updated-at type="datetime">2010-10-03T03:28:27Z</updated-at>
<id type="integer">12</id>
<password-salt>$2a$10$a2K.PXEXpgpWH6MMLD/AFe</password-salt>
<email>mail@recursive-design.com</email>
</user>
Luckily, you can disable specific fields using the except option :
respond_to do |format|
format.json { render :json => @user, :except=> [:encrypted_password, :password_salt] }
format.xml { render :xml => @user, :except=> [:encrypted_password, :password_salt] }
format.html
end
… which removes the offending fields from output :
<user>
<created-at type="datetime">2010-10-02T00:12:43Z</created-at>
<updated-at type="datetime">2010-10-03T03:28:27Z</updated-at>
<id type="integer">12</id>
<email>dave@recurser.com</email>
</user>
If you find yourself doing this in a lot of different places, it may be easier to filter these options at the model level, by over-riding the ’to_json’ and ’to_xml’ methods :
class User < ActiveRecord::Base
...
# Exclude password info from xml output.
def to_xml(options={})
options[:except] ||= [:encrypted_password, :password_salt]
super(options)
end
# Exclude password info from json output.
def to_json(options={})
options[:except] ||= [:encrypted_password, :password_salt]
super(options)
end
...
end