【问题标题】:Removing empty hashes {} from array in Active Model Serialized object从 Active Model 序列化对象中的数组中删除空哈希 {}
【发布时间】:2018-09-04 11:54:48
【问题描述】:

我有一些情况不想序列化当前对象并想跳过它。但是我还没有找到一种方法来做到这一点,所以我忽略了属性:foo 上的属性,如果::条件。这会在我的序列化对象中生成空 {} 。我该如何解决这个问题?

[
 {
  "id": 392027,
  "name": "ISC Board",
  "grades":[
            {
                "id": 333938,
                "name": "1",
                "subjects": [
                    {
                        "id": 571671,
                        "subject": "Math"
                    },
                    {
                        "id": 742980,
                        "subject": "Science"
                    },
                    {
                        "id": 186926,
                        "subject": "English"
                    },
                    {
                        "id": 658224,
                        "subject": "Social_Studies"
                    },
                    {},
                    {},
                    {}
                ]
            },
            {
                "id": 333943,
                "name": "2",
                "subjects": [
                    {
                        "id": 571671,
                        "subject": "Math"
                    },
                    {
                        "id": 742980,
                        "subject": "Science"
                    },
                    {
                        "id": 186926,
                        "subject": "English"
                    },
                    {
                        "id": 658224,
                        "subject": "Social_Studies"
                    },
                    {},
                    {},
                    {}
                ]
            },
          ]
 },
 {
  "id": 666627,
  "name": "NY Board",
  "grades":[
            {
                "id": 333938,
                "name": "1",
                "subjects": [
                    {
                        "id": 571671,
                        "subject": "Math"
                    },
                    {
                        "id": 742980,
                        "subject": "Science"
                    },
                    {
                        "id": 186926,
                        "subject": "English"
                    },
                    {
                        "id": 658224,
                        "subject": "Social_Studies"
                    },
                    {},
                    {},
                    {}
                ]
            },
            {
                "id": 432943,
                "name": "2",
                "subjects": [
                    {
                        "id": 571671,
                        "subject": "Math"
                    },
                    {
                        "id": 742980,
                        "subject": "Science"
                    },
                    {
                        "id": 186926,
                        "subject": "English"
                    },
                    {
                        "id": 658224,
                        "subject": "Social_Studies"
                    },
                    {},
                    {},
                    {}
                ]
            },
          ]
  }


]

序列化器看起来像这样-

class BoardSerializer < ActiveModel::Serializer
  #some code
  class GradeSerializer < ActiveModel::Serializer 
     has_many :subjects
     #some code
     class SubjectSerializer < ActiveModel::Serializer
        attribute :id, if: :condition
        attribute :name, key: :subject, if: :condition

        def condition
            #some code
            #returns true or false
            #will not return both :id and :subject if false- I want to 
            #skip this current object if condition fails. (returns {})
        end  
     end

   end
end

如何简单地跳过序列化程序中的当前对象或删除空哈希?谢谢

【问题讨论】:

  • 你的代码是什么样的?
  • @DennyMueller 更新了代码。

标签: ruby-on-rails active-model-serializers activemodel


【解决方案1】:

请检查这是否是预期的结果:

input.transform_values { |v| v.map {|e| e.transform_values { |vv| vv.class == Array ? vv.select { |ee| ee unless ee.empty? } : vv } } }

# => {:grades=>[{:id=>333938, :name=>"1", :subjects=>[{:id=>571671, :subject=>"Math"}, {:id=>742980, :subject=>"Science"}, {:id=>186926, :subject=>"English"}, {:id=>658224, :subject=>"Social_Studies"}]}]}


编辑: 以满足 OP 问题的变化。
input.map { |e| e.transform_values { |v| v.is_a?(Array) ? v.map {|ee| ee.transform_values { |vv| vv.is_a?(Array) ? vv.select { |eee| eee unless eee.empty? } : vv } } : v } }

# => [{:id=>392027, :name=>"ISC Board", :grades=>[{:id=>333938, :name=>"1", :subjects=>[{:id=>571671, :subject=>"Math"}, {:id=>742980, :subject=>"Science"}, {:id=>186926, :subject=>"English"}, {:id=>658224, :subject=>"Social_Studies"}]}, {:id=>333943, :name=>"2", :subjects=>[{:id=>571671, :subject=>"Math"}, {:id=>742980, :subject=>"Science"}, {:id=>186926, :subject=>"English"}, {:id=>658224, :subject=>"Social_Studies"}]}]}, {:id=>666627, :name=>"NY Board", :grades=>[{:id=>333938, :name=>"1", :subjects=>[{:id=>571671, :subject=>"Math"}, {:id=>742980, :subject=>"Science"}, {:id=>186926, :subject=>"English"}, {:id=>658224, :subject=>"Social_Studies"}]}, {:id=>432943, :name=>"2", :subjects=>[{:id=>571671, :subject=>"Math"}, {:id=>742980, :subject=>"Science"}, {:id=>186926, :subject=>"English"}, {:id=>658224, :subject=>"Social_Studies"}]}]}]

【讨论】:

  • 您的答案似乎有效,但我无法让它适用于我拥有的整个 json 结构。我已将此处的 json 输出结构更新为我实际得到的结构。看起来我需要在转换内部有另一个循环才能让它工作?
【解决方案2】:

这件事你可以使用#select!

input = {
  "grades":
       [
         {
           "id": 333938,
          "name": "1",
          "subjects":
            [
              {
                "id": 571671,
               "subject": "Math"
              },
              {
                "id": 742980,
               "subject": "Science"
              },
              {
                "id": 186926,
               "subject": "English"
              },
              {
                "id": 658224,
               "subject": "Social_Studies"
              },
              {},
              {},
              {}
            ]
         }
       ]
}

input[:grades].first[:subjects].select! { |i| !i.empty? }

【讨论】:

  • 这只是一个大的序列化输出对象的一小部分。我有一些嵌套的序列化程序正在运行,我需要通过条件忽略一些对象。在某些地方我渲染:json @object 触发序列化程序,在某些地方我运行ActiveModel::SerializableResource.new(@education_boards).serializable_hash.to_json
  • 我的回答只是一个如何摆脱空元素的例子。现在您只需将其应用于需要压缩的每个数组。
  • 有没有办法跳过序列化程序中的当前对象?
猜你喜欢
  • 2022-01-07
  • 2020-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-14
  • 2018-07-27
  • 2011-03-17
  • 1970-01-01
相关资源
最近更新 更多