Skip to content

Allow either string or procs to be used in formatting DateTime objects#145

Merged
mcclayton merged 9 commits intomasterfrom
allowProcDateTimeFormat
Apr 3, 2019
Merged

Allow either string or procs to be used in formatting DateTime objects#145
mcclayton merged 9 commits intomasterfrom
allowProcDateTimeFormat

Conversation

@mcclayton
Copy link
Copy Markdown
Contributor

@mcclayton mcclayton commented Apr 1, 2019

This aims to address #120

Previously, we had a global and field level option datetime_format which takes in a string representing the strptime format to format the Date/DateTime object. This PR enables datetime_format to be either a String or a Proc. This enables more flexibility/control in how dates can be formatted. ( i.e. for those who want to have something like integer UNIX timestamps)

This is something that can _technically already be achieved (only at the field-level) _ by passing a block directly to the field, however, now that datetime_format can be set globally, this allows us to set a global datetime_format Proc which will get invoked on any field that responds to strptime, and matching field-level syntax in a more idiomatic way.

Global Config Setting

If a global datetime_format is set (either as a string format or a Proc), this option will be
invoked and used to format all fields that respond to strptime.

Blueprinter.configure do |config|
  config.datetime_format = ->(datetime) { datetime.nil? ? datetime : datetime.strftime("%s").to_i }
end

Field-level Setting

Usage (String Option):

class UserBlueprint < Blueprinter::Base
  identifier :name
  field :birthday, datetime_format: "%m/%d/%Y"
end

Output:

{
  "name": "John Doe",
  "birthday": "03/04/1994"
}

Usage (Proc Option):

class UserBlueprint < Blueprinter::Base
  identifier :name
  field :birthday, datetime_format: ->(datetime) { datetime.nil? ? datetime : datetime.strftime("%s").to_i }
end

Output:

{
  "name": "John Doe",
  "birthday": 762739200
}

Comment thread README.md
"birthday": 762739200
}
```

This comment was marked as resolved.

format = field_format || Blueprinter.configuration.datetime_format
format.nil? ? value : value.strftime(format)

if format.nil?

This comment was marked as resolved.

elsif format.is_a?(String)
value.strftime(format)
else
raise BlueprinterError, 'Cannot format DateTime object with invalid formatter'

This comment was marked as resolved.

This comment was marked as resolved.

field :first_name, datetime_format: -> datetime { datetime.strftime("%s") }
end
end
it('raises a BlueprinterError') { expect{subject}.to raise_error(Blueprinter::BlueprinterError) }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm the error here is based on us using a datetime formatter on an invalid field, correct? The error message we get reads 'Cannot format DateTime object with invalid formatter' The formatter in this test case is perfectly fine, no? I think we need an invalid field error or something.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind I was confused. The message DOES NOT read 'Cannot format DateTime object with invalid formatter', rather it's 'Cannot format invalid DateTime object' which is perfectly valid.

@@ -1,13 +1,15 @@
module Blueprinter
class DateTimeFormatter
InvalidDateTimeFormatterError = Class.new(BlueprinterError)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@mcclayton mcclayton merged commit 36a867d into master Apr 3, 2019
@mcclayton mcclayton deleted the allowProcDateTimeFormat branch April 3, 2019 18:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants