ruby-on-railsapirails-apisti

Blueprinter gem - render STI collection


I'm trying to use the new alternative for serialization: Blueprinter

How do you handle STI collection where every model is some type of view?

I came up with something like this (saw similar code on AMS github issue):

def serialize_cards(cards)
  cards.group_by(&:type).map do |type, cards|
    case type
    when 'TypeOneCard' then Api::V1::CardBlueprint.render(cards, view: :one)
    when 'TypeTwoCard' then Api::V1::CardBlueprint.render(cards, view: :two)
    else  raise ArgumentError, "Unhandled event type '#{type}'"
    end
  end
end

Why is output in string with backslashes:

[
    "[{\"id\":27566,\"attachment\":null,\"avatar\":null,\"card_comments_count\":0,\"card_likes_count\":0,\"card_publisher\":\"group\",\"created_at\":\"2020-11-18T10:24:42.195+01:00\",\"description\":\"Ted, how many times have I told you to put the lid back on the peanut butter jar?! It’s this inconsiderate, immature jackassery that makes me feel like I’m living in The Real World House! And not the early days when they all had jobs and social consciences, I’m talking about Hawaii, and after!\",\"ends_at\":\"2021-02-06T23:55:00.000+01:00\",\"event_attendees_count\":0,\"group_name\":\"Cheeseburger - Herbes de Provence\",\"origin\":\"http://localhost:3000/dorfplatz/3\",\"origin_name\":\"Dardagny - Athenaz (Avusy)\",\"picture\":null,\"starts_at\":\"2020-11-21T00:00:00.718+01:00\",\"title\":\"The Doors\",\"type\":\"EventCard\",\"updated_at\":\"2020-11-19T10:25:49.467+01:00\",\"user_full_name\":\"Carolann Ritchie\"},{\"id\":28163,\"attachment\":null,\"avatar\":null,\"card_comments_count\":0,\"card_likes_count\":0,\"card_publisher\":\"group\",\"created_at\":\"2020-11-14T23:22:42.059+01:00\",\"description\":\"That’s life, you know, we never end up where you thought you wanted to be.\",\"ends_at\":\"2020-12-05T23:55:00.000+01:00\",\"event_attendees_count\":0,\"group_name\":\"Cheeseburger - Herbes de Provence\",\"origin\":\"http://localhost:3000/dorfplatz/3\",\"origin_name\":\"Dardagny - Athenaz (Avusy)\",\"picture\":null,\"starts_at\":\"2020-11-14T00:00:00.942+01:00\",\"title\":\"Iron Maiden\",\"type\":\"EventCard\",\"updated_at\":\"2020-11-19T10:25:59.622+01:00\",\"user_full_name\":\"Reuben Kertzmann\"},{\"id\":24658,\"attachment\":null,\"avatar\":null,\"card_comments_count\":0,\"card_likes_count\":0,\"card_publisher\":\"group\",\"created_at\":\"2020-11-14T14:40:45.442+01:00\",\"description\":\"You can’t just skip ahead to where you think your life should be.\",\"ends_at\":\"2021-02-04T23:55:00.000+01:00\",\"event_attendees_count\":0,\"group_name\":\"Cheeseburger - Herbes de Provence\",\"origin\":\"http://localhost:3000/dorfplatz/3\",\"origin_name\":\"Dardagny - Athenaz (Avusy)\",\"picture\":null,\"starts_at\":\"2020-11-19T00:00:00.811+01:00\",\"title\":\"Steely Dan\",\"type\":\"EventCard\",\"updated_at\":\"2020-11-19T10:24:58.452+01:00\",\"user_full_name\":\"Reuben Kertzmann\"}]",

Solution

  • Use render_to_hash instead of outputting each serializer as JSON

    def serialize_cards(cards)
      cards.group_by(&:type).map do |type, cards|
        case type
        when 'TypeOneCard' 
          Api::V1::CardBlueprint.render_to_hash(cards, view: :one)
        when 'TypeTwoCard' 
          Api::V1::CardBlueprint.render_to_hash(cards, view: :two)
        else  
          raise ArgumentError, "Unhandled event type '#{type}'"
        end
      end
    end