首页 > 解决方案 > 如何从 ActiveSerializer 加载嵌套的 json?

问题描述

我想为 JSON 导入/导出系统开发方法。

举一个简单的例子,我们有一只带爪子的猫,我做了这个:

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

文件中的 JSON 是:

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

但是当我运行 json_import 时,我得到了那个错误:

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

我在文档中没有找到与我的问题相关的“from_json”,而且我也没有成功找到有关该问题的资源。没有宝石有没有办法做到这一点?(如果我需要一个,我会考虑它)。

标签: ruby-on-railsjsonserializationactiverecorddeserialization

解决方案


您在paws键名上有问题,解决使用键名paws_attributes

查看属性所需的键名accepts_nested_attributes_for

你的.txt文件内容应该是这样的

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

解决方案:

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

并添加一种自定义as_json方法,如下所述。

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

推荐阅读