Reputation: 71
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
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}]}
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