views:

408

answers:

3

Hi all,

I am aware that ActiveRecord provides a to_json method which allows fields to be filtered out of the JSON output using :only and :except.

At present I am using the following to format an array from a find as JSON:

@customers = Customer.find(:all)
...
format.js { render :json => @customers}

How would I be able to select the fields to be output in the objects in the array? Is there a shortcut or do I need to do this by hand?

Cheers, Adam

A: 

If you peep into the ActionController::Base class, you'll see that it calls to_json on your collection immediately (no extra options used), so you've got to have it already prepared. So if in your action you don't use the attributes that are not rendered to json, you can replace your find with

@customers = Customer.find(:all, :select => ["id", ...])

to select only the ones that you need.

neutrino
+2  A: 

You can overwrite the to_json method of the model class if you want to globally apply the change for the model.

For example, to exclude null values from the rendered JSON you could overwrite the original ActiveRecord method to_json

  def to_json(options)
    hash = Serializer.new(self, options).serializable_record
    hash = { self.class.model_name => hash } if include_root_in_json
    ActiveSupport::JSON.encode(hash)
  end

with this in your model class:

  def to_json(options)
    hash = Serializer.new(self, options).serializable_record.reject {|key, value| value.nil? }
    hash = { self.class.model_name => hash } if include_root_in_json
    ActiveSupport::JSON.encode(hash)
  end
Arrel
+1  A: 

I think you answered your own question. With Rails 2.3.x you could use the following:

@customers = Customer.all #Shortcut for to Customer.find(:all)
respond_to do |format|
  format.js { render :json => @customers.to_json(:only=>[:column_one, :column_two]}
end
Scott