What is a good practice to create a JSON string of one object (object of
class A) containing an array of objects (objects of class B)? I am
particularly interessted in the implementation of class’s A to_json
method.
Assuming class A looks as follows:
class A
attr_accessor :items
def initialize() @items = Array.new
end
def to_json(*a)
?SECRET OF THE DAY?
end
end
and class B:
class B
def to_json(*a)
{“class B” => “class B”}.to_json(*a)
end
end
The best solution I got so far is:
def to_json(*a)
json = Array.new @items.each do |item|
json << item.to_json(*a)
end
{“class A” => json}.to_json(*a)
end
Assuming there is only one item in array of an object of class A, the
resulting JSON string looks as follows:
{“class A”:["{“class B”:“class B”}"]}
I also tried:
def to_json(*a)
{“class A” => @items}.to_json(*a)
end
But it results in IOError exception in class A, saying to_json “not
opened for reading”…
But it results in IOError exception in class A, saying to_json “not
opened for reading”…
I am sure we can do better?
I think it would be much better to make the class an attribute of the
JSON object, not build a new JSON object of {class => {attributes}}
If you look at the tests/ directory of the json or json_pure gem, you’ll
see that they use ‘json_class’ for this purpose. e.g.
class A
def initialize(a) @a = a
end
attr_reader :a
def ==(other)
a == other.a
end
def self.json_create(object)
new(*object['args'])
end
def to_json(*args)
{
'json_class' => self.class.name,
'args' => [ @a ],
}.to_json(*args)
end
end
The use of the ‘args’ element (being the array of arguments to #new) is
fairly ugly. I would rather expose the instance variables as members of
the JSON object:
class A
def initialize(a) @a = a
end
attr_reader :a
def self.json_create(object)
new(object['a'])
end
def to_json(*args)
{
'json_class' => self.class.name,
'a' => @a,
}.to_json(*args)
end
I want to use to_json capability within a rails project. In my project,
I created class A and B as well as a controller to call the to_json
method. I got:
{“json_class”:“A”,“items”:[{},{}]}
After that, I reinstalled json and json_pure, using version 1.5.1 of
both now.
And here is a working example for your code where class A includes
instances of class B:
$ cat ert2.rb
require ‘rubygems’
require ‘json’
class A
attr_accessor :items
def initialize() @items = Array.new
end
def to_json(*a)
{
“json_class” => self.class.name,
“items” => @items,
}.to_json(*a)
end
end
class B
def to_json(*a)
{
“json_class” => self.class.name,
}.to_json(*a)
end
end