2

I am currently trying to incorporate attributes in the API of my Rails app. The use case is simple. I have a User model:

class User < ActiveRecord::Base
  attr_accessible :email
end

I have another model, basically linking the users to an Event:

class UserEvent < ActiveRecord::Base
  belongs_to :user
  belongs_to :event
end

I want to be able to list all users related to an event using the UserEvent model through an API accessible as JSON or XML, and I would like the email of my UserEvent to appear in both XML and JSON dump.

This question suggests that I can just override serialiable_hash, well this appears to work only for JSON, as it looks like serializable_hash is not used by to_xml

Another approach I have investigated was to override the attributes method in my class:

class UserEvent < ActiveRecord::Base
   def attributes
    @attributes = @attributes.merge "email" => self.email
    @attributes
  end
end

This works well for JSON, but throws an error when trying the XML version:

undefined method `xmlschema' for "2011-07-12 07:20:50.834587":String

This string turns out to be the "created_at" attribute of my object. So it looks like I am doing something wrong on the hash I am manipulating here.

Community
  • 1
  • 1
rpechayr
  • 1,282
  • 12
  • 27

1 Answers1

2

You can easily add additional nested data into API responses using include. Here's an example:

respond_with(@user, :include => :user_event )

You should also add the reverse association in User:

has_many :user_events

You can pass in an array to :include for multiple models. It'll serialize and nest them in the response appropriately.

Logan Leger
  • 662
  • 3
  • 10
  • What I did not mention in my question is that I want to do this in the model because it must be taken into account in several controllers. – rpechayr Mar 10 '12 at 14:56
  • 1
    No problem! Just override `as_json` in your model. This method gets called every time a model object is serialized to JSON, so it'll get used everywhere. `def as_json(options = {}) super options.merge(include: :user_event) end` – Logan Leger Jun 10 '12 at 07:19