0

I have a few conditions where don't want to serialize the current object and want to skip it. But i haven't found a way to do that so I am ignoring attributes on attribute :foo, if: :condition. And this is generating empty {} in my serialized object inside arrays. How do I fix this?

[
 {
  "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"
                    },
                    {},
                    {},
                    {}
                ]
            },
          ]
  }


]

serializer looks something like this-

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

How do I simply skip the current object in the serializer or remove empty hashes? Thanks

2
  • What does you code look like? Commented Sep 4, 2018 at 12:02
  • @DennyMueller Updated Code. Commented Sep 4, 2018 at 17:14

2 Answers 2

1

Please, check if this is the expected result:

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


EDIT: to meet changes in OP question.

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"}]}]}]
Sign up to request clarification or add additional context in comments.

1 Comment

your answer seems to be working but im not able to get it to work for the entire json structure I have. I have updated the json output structure here to what I actually get. It looks like i need to have another loop inside the transform to get it to work?
0

You can use #select! for this matter:

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? }

3 Comments

this is just a small part of a big serialized output object. I have a few nested serializers running and I need to ignore some of the objects through condition. At some places I render :json @object which triggers the serializer and at some place I run ActiveModel::SerializableResource.new(@education_boards).serializable_hash.to_json
My answer is just an example of how to get rid of empty elements. Now you just have to apply it to each array that needs to be compacted.
is there way to skip current object in serializer?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.