从活动模型序列化对象中的数组中删除空哈希 {}

Removing empty hashes {} from array in Active Model Serialized object

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

[
 {
  "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

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

这件事你可以用#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? }

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

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"}]}]}]