Neustrony
Neustrony

Reputation: 71

How to load nested json from ActiveSerializer?

I want to develop methods for a JSON import/export system.

With a simple example where we have a cat with paws, I made this :

class Cat < ApplicationRecord
  has_many :paws

  def json_export
    json = self.to_json(include: :paws)
    File.open("some_file_name.txt", "w") { |file| file.puts json }
  end

  def self.json_import
    Cat.new.from_json(File.open("some_file_name.txt", "rb").read)
  end
end

# I put Paw code below FYI

class Paw < ApplicationRecord
 belongs_to :cat
end

The JSON present in the file is :

{"id":1,"name":"Felix","paws":[{"id":1,"color":"red","cat_id":1}]}

But when I run json_import I got that error :

ActiveRecord::AssociationTypeMismatch: Paw(#69870882049060) expected, got {"id"=>1, "color"=>"red", "cat_id"=>1} which is an instance of Hash(#47217074833080)

I found nothing in the doc for 'from_json' related to my problem, and I'm not successful neither for finding resources about that. Is there a way to do that without gems? (If I need one I will consider it however).

Upvotes: 2

Views: 115

Answers (1)

7urkm3n
7urkm3n

Reputation: 6311

You had an issue on paws key name, to solve use key name paws_attributes

look at attributes required key name accepts_nested_attributes_for

Your .txt file content supposed to look like this

{"id":1,"name":"Felix","paws_attributes":[{"id":1,"color":"red","cat_id":1}]}

Solution:

json = self.to_json({include: :paws, as: :paws_attributes})

and add one of custom as_json method, mentioned below.

class Cat < ApplicationRecord
  has_many :paws
  accepts_nested_attributes_for :paws

  def as_json(options = {})
    hash = super(options)
    hash[options[:as].to_s] = hash.delete(options[:include].to_s) if options.key? :as
    hash
  end
  
  #OR

  #  if want to use custom key names
  def as_json(options = {})
    json = {id: id, name: name} # whatever info you want to expose
    json[options[:as].to_s] = paws.as_json if options[:as]
    json
  end
  
  ...

end

Upvotes: 2

Related Questions