Search code examples
ruby-on-railsjsonapi-design

Custom Output rails json api with :include


Right now I have my api rendering this json

[
       {
              "id": 1,
              "name": "1",
              "matches": [{
                            "score_a": 1,
                            "score_b": 3,
                            "time": "2016-05-20T15:00:00.000Z",
                             "teams": [
                                        {
                                          "name": "Team 1",
                                           "logo_url":"test.jpg"
                                          },
                                         {
                                           "name": "Team 2",
                                           "logo_url": "test.2jpg"
                                          }
                                        ]
                            }]

   }
]

I am rendering this using the render :json helper of Rails. Like this:

@calendar = Journey.all

render json: @calendar, include: { matches: 
                                     { include: { teams: { } }} 
                                  }            

How ever, the front end developer (He is consuming the API through Angular) is asking me the change the structure of the JSON, he needs the teams to be in the same level as the match. Some thing like this:

[
       {
              "id": 1,
              "name": "1",
              "matches": [{
                            "score_a": 1,
                            "score_b": 3,
                            "time": "2016-05-20T15:00:00.000Z",
                             "team_a_name": "Team 1",
                             "team_a_logo_url":"test.jpg",
                             "team_b_name": "Team 2",
                             "team_b_logo_url": "test.2jpg",

                            }]

   }
]

As you can see the the matches an the teams are now merged.

How can I achieve this?

Cheers!


Solution

  • I just replaced alphabets with digits

      teams = [
                {
                   "name": "Team 1",
                   "logo_url":"test.jpg"
                },
                {
                   "name": "Team 2",
                   "logo_url": "test.2jpg"
                }
              ]
    

    teams is your given hash

      array = []
    
      teams.count.times {|i| 
           teams[i].keys.each do |k,v|
              key = "team_"+ (i+1).to_s + "_"+k.to_s
              array.push(key)
           end
       }
    
      #=> ["team_1_name", "team_1_logo_url", "team_2_name", "team_2_logo_url"] 
    

    Now we will create array for your values

     value_array = []
    
     teams.each do |k|
        k.each do |key, val|
          value_array.push(val)
        end
     end
    
    #=> ["Team 1", "test.jpg", "Team 2", "test.2jpg"]
    

    Now we are going to combine both arrays

     new_teams = Hash[*array.zip(value_array).flatten]
     #=> {"team_1_name"=>"Team 1", "team_1_logo_url"=>"test.jpg", "team_2_name"=>"Team 2", "team_2_logo_url"=>"test.2jpg"} 
    

    now you can assign new_teams in your json

    render json: @calendar, include: { matches: 
                                     { include: { teams: new_teams }} 
                                  }