views:

30

answers:

2

Here's a simple ActiveResource class. It has some instance variables and maybe even some methods, but it's not backed by any data.

ruby-1.8.7-p299 > class Box < ActiveResource::Base;
                    attr_accessor :a, :b, :c, :d;
                  end
 => nil

Let's populate it:

ruby-1.8.7-p299 > bx = Box.new; bx.a = 100; bx.b = 200;
                                bx.c = 300; bx.d = 400;
                                bx
 => #<Box:0xb5841c54 @attributes={}, @b=200, @a=100,
       @prefix_options={}, @c=300, @d=400> 

So far so good. How about we cherry-pick some of those instance variables for its JSON model? Say that we only care about b and c but not a, d, or anything else.

ruby-1.8.7-p299 > bx.to_json({:only => ['b', 'c']})
 => "{}"

That doesn't work, however, since we have no attributes called 'b' or 'c', only values. How can we wind up with something like this?

{ "box": { "b": 200, "c": 300 } }

Even better, can we get this without having to inherit from ActiveResource?

+1  A: 

In an AR object, you just use the 'methods' param to to_json, like on this page: http://www.gregbenedict.com/2007/11/28/outputting-custom-model-attributes-with-to_json/ .

In a non AR object, just define a custom to_json method, where you assemble a hash of the variables you want to json-ize, then to_json it, and return it. Like, here's an (untested) example:

def to_json(options = {})
  {"box" => {"b" => b, "c" => c}}.to_json(options)
end
jasonpgignac
Thanks for your reply, Jason. Two quick things: note that I'm using ActiveResource here, not ActiveRecord. Also, I'm not sure that `methods` will work here: `bx.to_json(:methods => [:b, :c])` produces a hash containing everything. Second, isn't writing `"b" => b, "c" => c, ...` going to be pretty repetitive? Is there a way I can just specify the attributes to JSON-ize?
Kyle Kaitan
My bad, on the active resource! Sorry, I missed that :DIn regards to what you were asking: You could always just take a list of symbols or strings to represent the methods you want to put in the JSON response. I'll edit my response above to clarify that, if it's more like what you are looking for?
jasonpgignac
A: 

Try using YAJL-ruby to encode your hashes to json format.

require 'yajl'
hash = {:only => ['b', 'c']}
Yajl::Encoder.encode(hash)
=> "{\"only\":[\"b\",\"c\"]}"

http://rdoc.info/projects/brianmario/yajl-ruby

nicholasklick