trailblazer / roar

Parse and render REST API documents using representers.

Home Page:http://www.trailblazer.to/gems/roar

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Custom Formats for DateTime support

seniorihor opened this issue · comments

Hi,

It doesn't seem possible to represent timestamp properties in certain (or default) format.

Steps to reproduce

config/initializers/date_format.rb

Time::DATE_FORMATS[:default] = "%Y-%m-%dT%H:%M:%S.%N%z!!!"

It converts timestamp to proper format:

song.created_at.to_s
=> "2017-04-05T19:10:47.146095000+0000!!!"

app/representers/song_representer.rb

class SongRepresenter < Roar::Decorator
  include Roar::JSON

  property :created_at
end

Actual behavior

Anyway, it renders not expected output:

SongRepresenter.new(song).to_json
=> "{\"created_at\":\"2017-04-05T19:10:47Z\"}"
# expected: "{\"created_at\":\"2017-04-05T19:10:47.146095000+0000!!!\"}"

Please, help me understand if it's a bug or find a way to achieve expected result.

System configuration

Roar version: 1.1.0

Same here! Adding myself to the loop!

Try this:

property :created_at, exec_context: :decorator

def created_at; super.to_s; end

Thanks for the input, @apotonick. I'm trying to change the format for DateTime to UNIX epoch format, depending on a request parameter. Adding your solution, doesn't work for me in this case, do you have maybe a different approach?

Thanks for your time and effort in setting up this gem and maintaining it!

@nlsrchtr Rendering or parsing?

The idea was to have it both way. Currently I found a workaround, by changing the params before they hit the stack and changing:

module ActiveSupport
  class TimeWithZone
    def as_json(options = nil)
      if ActiveSupport::JSON::Encoding.use_standard_json_time_format
        xmlschema
      else
        time.strftime("%s%L").to_i
      end
    end

    def to_json(*args)
      as_json.to_json(*args)
    end
  end
end

It works, but feels way too hacky...

I want to vomit! 🤢

Can I see your representer class?

🤣

The requirement is, that it should be possible to switch between "UNIX epoch format" and ISO8601 on a request base (based on some header attribute).

The call is also pretty plain and simple with:

API::V1::Me::UnitBookingRepresenter.new(current_user.unit_bookings.new).from_json(permitted_params.to_json)

The representer class looks like this

require "roar/json/json_api"
module API
  module V1
    module Me
      class UnitBookingRepresenter < Roar::Decorator
        include Roar::JSON::JSONAPI.resource :unit_bookings

        attributes do
          property :unit_id
          [...]
          property :starts_at
          property :ends_at
        end
      end
    end
  end
end

Thanks for your time and effort!

On a sidenote: You don't need strong_parameters with Roar/Representable, it filters automatically, the way it should be.

Hm, this is a JSONAPI issue and should be posted on https://github.com/trailblazer/roar-jsonapi - in pure Roar, my "trick" would be working™.