【问题标题】:JSON with full hierarchy in Rails在 Rails 中具有完整层次结构的 JSON
【发布时间】:2023-04-08 12:37:02
【问题描述】:

我的应用中有一个层次结构:

  • 环境有容器
  • 容器有物品
  • 项目有表情

所以我的模型代码如下所示:

class Environment < ActiveRecord::Base
  has_many :containers, :dependent => :destroy

  def as_json(options = {})
    super(options.merge(include: :containers))
  end

end

class Container < ActiveRecord::Base
  has_many :items, :dependent => :destroy
  belongs_to :environment

  def as_json(options = {})
    super(options.merge(include: :items))
  end

end

class Item < ActiveRecord::Base
  has_many :expressions, :dependent => :destroy
  belongs_to :container

  def as_json(options = {})
    super(options.merge(include: :expressions))
  end

end

class Expression < ActiveRecord::Base
  belongs_to :item

def as_json(options = {})
  super()
end

end

定期获取记录我通常只需要低于所需记录的一个层次结构,这就是为什么在as_json 中我只向下合并一个层次结构(获取环境将返回一组容器但那些容器不会有物品)

我的问题:

现在我需要向控制器添加一个方法,以允许完整的层次结构响应,即GET /environment/getFullHierarchy/3 将返回:id=3 的环境及其所有容器和每个容器all it's Items & for each Item all it's expressions. 不破坏当前的 as_json

我对 Rails 有点陌生,正在使用 Rails 4.2.6 并且不知道从哪里开始 - 谁能帮忙?

【问题讨论】:

标签: ruby-on-rails json ruby-on-rails-4


【解决方案1】:

当然是这样的,希望你能明白。

EnvironmentSerializer.new(environment) 获取层次结构 json。

假设环境表有列 environment_attr1 , environment_attr2

class EnvironmentSerializer < ActiveModel::Serializer
  attributes :environment_attr1, :environment_attr2 , :containers

  # This method is called if you have defined a 
  # attribute above which is not a direct value like for
  # a rectancle serializer will have attributes length and width
  # but you can add a attribute area as a symbol and define a method
  # area which returns object.length * object.width
  def containers
     ActiveModel::ArraySerializer.new(object.containers,
           each_serializer: ContainerSerializer)
  end
end

class ContainerSerializer < ActiveModel::Serializer
   attributes :container_attr1, :container_attr2 , :items
   def items
     ActiveModel::ArraySerializer.new(object.items,
        each_serializer: ItemSerializer)
   end
end



   class ItemSerializer < ActiveModel::Serializer
   ... 
   end

   class ExpressionSerializer < ActiveModel::Serializer
   ... 
   end

【讨论】:

  • 这显然可以更好地写一个例子
  • 您也可以将containersitems 方法替换为has_many :containers, serializer: ContainerSerializerhas_many :items, serializer: ItemSerializer。我相信这会产生相同的效果,并且更像 ActiveModelSerializer-ish。
  • 这看起来很有希望,但是我怎样才能保持我原来的行为——调用 :index 时——只检索层次结构的下一层,控制器在这两个序列化程序中的外观如何?
  • 原始行为保持不变,记住 EnvironmentSerializer.new(environment).to_json 会给你层次结构。
猜你喜欢
  • 2019-03-02
  • 1970-01-01
  • 2013-12-22
  • 1970-01-01
  • 2013-12-11
  • 2018-11-12
  • 1970-01-01
  • 2020-03-09
  • 2016-12-07
相关资源
最近更新 更多