trailblazer / roar-jsonapi

JSON API support for Roar.
http://trailblazer.to/gems/roar/jsonapi.html
MIT License
42 stars 18 forks source link

JSON API dasherize property names #13

Closed myabc closed 7 years ago

myabc commented 7 years ago

From @thhermansen on November 30, 2015 14:31

Hi,

I wasn't able to figure this one out myself. Given the following:

class User < Roar::Decorator
  include Roar::JSON::JSONAPI

  property :full_name
end

Is there a way to make the serialised version of a user to have property named full-name?

I can solve it by using #property's as-option, but I'd like to dasherize all property names automatically.

Copied from original issue: trailblazer/roar#173

myabc commented 7 years ago

From @apotonick on November 30, 2015 21:2

Yes, here you go: http://trailblazer.to/gems/representable/3.0/api.html#defaults

myabc commented 7 years ago

From @thhermansen on December 1, 2015 8:56

Thank you for pointing me to defaults. I had forgotten that I had tried it a week or two ago. It didn't seem be inherited in nested properties and has_one. Maybe it isn't supposed to. To give a complete example of what I have, without calling defaults:

require 'roar/decorator'
require 'roar/json/json_api'

module PlaytimeTube
  module Representers
    class Playback < Roar::Decorator
      include Roar::JSON::JSONAPI

      type :playbacks

      property :id
      property :starts_at, as: 'starts-at', render_nil: true
      property :duration_in_seconds, as: 'duration-in-seconds'
      property :type

      property :recording do
        property :local_id, as: 'local-id'
        # more properties
        property :artist_name, as: 'artist-name'
      end

      has_one :playtime_report, as: 'playtime-report' do
        type 'playtime-reports'

        property :id
        # more properties
        property :archive_url, as: 'archive-url'
      end
    end
  end
end

If i provide defaults with a block which dasherize the name right above type :playbacks it works for the Playback's properties, like starts_at, but it doesn't inherit to local_id within recording, nor in to playtime_report's properties like archive_url.

I can call defaults within property/has_one and it will work. Is there a better way, or should I simply use defaults within each given block?

myabc commented 7 years ago

From @apotonick on December 3, 2015 8:19

Defaults are not "inherited" into nested representers. I need to think about if that's a good idea or if we should introduce a inline: true option or something.

Will let you know tomorrow!

myabc commented 7 years ago

From @thhermansen on December 3, 2015 9:17

Oki, thank you. I solved it for now by doing:

DASHERIZE_NAME = -> (name, options) { {as: dasherize-the-string(name) } }
defaults &DASHERIZE_NAME

And reuse that block of code in the nested representers.