I have a rails application and a class I've wrote as a part of it (not an ActiveRecord or anything..). The data is stored in simple instance variables (string, integers, arrays...)
When I invoke to_json
on an instance of it I get what I expect to. A JSON object, containing all instance variables as JSON objects too.
However, when I add include Enumerable
to the class definition, the behavior of to_json
changes and I get an empty object: "[]"
Any idea why is that? Does Enumerable
somehow defined or undefines something that affects to_json
?
Thanks!
So, what happens is:
Rails loads in ActiveSupport. ActiveSupport injects (monkey patches) these as_json
methods into several classes and modules, including Enumerable
:
module Enumerable
def as_json(options = nil) #:nodoc:
to_a.as_json(options)
end
end
You're probably returning nothing for the each
method Enumerable requires you to have, so to_a
returns []
, and an empty array gets converted into the String "[]"
.
What you can do here, is, to bind your object into a non-enumerable inherited class, and use its .as_json
method.
Like this:
class A
def as_json(*)
Object.instance_method(:as_json).bind(self).call
end
end
Demo:
➜ pry
require 'active_support/all'
=> true
class A
def initialize
@a = 1
end
end
=> nil
A.new.to_json
=> "{\"a\":1}"
class A
include Enumerable
def each
end
end
=> nil
A.new.to_json
=> "[]"
class A
def as_json(*)
Object.instance_method(:as_json).bind(self).call
end
end
=> nil
A.new.to_json
=> "{\"a\":1}"