ruby-on-railsjsonruby-on-rails-4json-apirepresentable

Rails 4: Parsing JSONAPI using representable gem


I have the following working representer working for flat JSON:

# song_representer_spec.rb
require 'rails_helper'
require "representable/json"
require "representable/json/collection"

class Song < OpenStruct
end

class SongRepresenter < Representable::Decorator
  include Representable::JSON
  include Representable::JSON::Collection

    items class: Song do
      property :id
      nested :attributes do
        property :title
      end
    end  
end

RSpec.describe "SongRepresenter" do

  it "does work like charm" do
    songs = SongRepresenter.new([]).from_json(simple_json)
    expect(songs.first.title).to eq("Linoleum")
  end

  def simple_json
    [{
      id: 1,
      attributes: {
        title: "Linoleum"
      }
        }].to_json
  end
end

We are now implementing the specifications of JSONAPI 1.0 and I cannot figure out how to implement a representer able to parse the following json:

{
  "data": [
    "type": "song",
    "id": "1",
    "attributes":{
      "title": "Linoleum"
    }
  ]
}

Thank you in advance for hints and suggestions

Update:

Gist containing a working solution


Solution

  • require 'representable/json'
    
    
    
    class SongRepresenter < OpenStruct
      include Representable::JSON
    
      property :id
      property :type
      nested :attributes do
        property :title
      end
    
    
    end
    
    
    class AlbumRepresenter < Representable::Decorator
      include Representable::JSON
    
      collection :data, class: SongRepresenter
    
    
    end
    
    
    hash = {
      "test": 1,
        "data": [
        "type": "song",
          "id": "1",
          "attributes":{
              "title": "Linoleum"
          }
      ]
    }
    
    decorator =   AlbumRepresenter.new(OpenStruct.new).from_json(hash.to_json)
    

    You can now iterate your data array and access to SongRepresenter properties:

    2.2.1 :046 > decorator = AlbumRepresenter.new(OpenStruct.new).from_json(hash.to_json)
    => #<OpenStruct data=[#<SongRepresenter id="1", type="song", title="Linoleum">]> 
    2.2.1 :047 > decorator.data
    => [#<SongRepresenter id="1", type="song", title="Linoleum">] 
    

    Please note the difference using hash or JSON.parse(hash.to_json)

    2.2.1 :049 > JSON.parse(hash.to_json)
    => {"test"=>1, "data"=>[{"type"=>"song", "id"=>"1", "attributes"=>{"title"=>"Linoleum"}}]} 
    2.2.1 :050 > hash
    => {:test=>1, :data=>[{:type=>"song", :id=>"1", :attributes=>{:title=>"Linoleum"}}]} 
    

    So, using AlbumRepresenter.new(OpenStruct.new).from_hash(hash) doesn't works, because symbolized keys.