Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

to_json on ActiveRecord object ruby 3.0

I am using rails 6.0.3.6 and ruby 3.0.0,

When I call {'user' : User.first }.to_json I am getting "{\"user\":\"#<User:0x00007fa0a8dae3c8>\"}"

same with [User.first, User.last].to_json

If I switch back to ruby 2.7.2, I get proper result ie <User:0x00007fa0a8dae3c8> replaced with all it's attributes.

Any idea what I am missing?

like image 245
pk-n Avatar asked Oct 15 '22 21:10

pk-n


1 Answers

The problem is in Rails 6.0.3.6 when invoking to_json on {'user' : User.first } Rails end up adding a JSON::Ext::Generator::State argument for to_json, so options.is_a?(::JSON::State) returns true and super(options) is returned.

From the definition of to_json:

def to_json(options = nil)
  if options.is_a?(::JSON::State)
    # Called from JSON.{generate,dump}, forward it to JSON gem's to_json
    super(options)
  else
    # to_json is being invoked directly, use ActiveSupport's encoder
    ActiveSupport::JSON.encode(self, options)
  end
end

While in more recent of Rails to_json is invoked without any argument and the branch takes the path to finally return ActiveSupport::JSON.encode(self, options).

So, in your case you could do

{ 'user': User.first.attributes }.to_json

To bypass the problem.

like image 66
Sebastian Palma Avatar answered Oct 24 '22 12:10

Sebastian Palma