Decorator Dryer
Welcome to Decorator Dryer! The aim of this gem is to help you write smaller, DRYer, easier to maintain, decorators.
Decorator Dryer contains a collection of formatters that cover some of the more common things that developers do in their decorators. On top of those formatters is a layer of shortcuts to help you reduce the amount of code in your decorator classes.
This is not a fully-formed decorator framework. Decorator Dryer is intended as a companion for Draper.
Installation
Add this line to your application's Gemfile:
gem 'draper'
gem 'decorator_dryer'
And then execute:
$ bundle install
Configuration
Formatters
The formatters in Decorator Dryer use a set of default formats for things like dates and times.
If you are happy with the defaults, you can skip this section. However, if you would like to set your own defaults, you can do so with an initializer.
DecoratorDryer.configure do |config|
config.date_format = "%Y-%m-%d"
config.humanized_date_format = "%d/%m/%Y"
config.datetime_format = "%Y-%m-%d %H:%M"
config.humanized_datetime_format = "%H:%M %d/%m/%Y"
config.time_format = "%H:%M"
end
Attachments
Decorator Dryer also provides shortcuts for attachments. There will be more detail on these shortcuts in later sections.
This can also be configured via an initializer.
DecoratorDryer.configure do |config|
config.attachment_shortcuts.mode = :none
config.attachment_shortcuts.default_preview_transform = :none
end
Attachment shortcuts are disabled by default. To enable them, you can set config.attachment_shortcuts.mode = :active_storage
Please note that this gem currently only provides shortcuts for Active Storage attachments.
You can also set a default transform for your attachment previews.
This could either be a variant, with something like:
config.attachment_shortcuts.default_preview_transform = :thumb
Or, a representation with something like:
config.attachment_shortcuts.default_preview_transform = { resize: "400x" }
Usage
Decorator Dryer is not a complete decorator library. It is intended for use alongside Draper. Why reinvent the wheel when there is already such a good option out there?
You can use Decorator Dryer by either adding the shortcuts to your decorator classes or by directly calling the formatters from within your decorator methods.
Shortcuts
class PersonDecorator < Draper::Decorator
include DecoratorDryer
to_date_format :date_of_birth
to_datetime_format :moment_of_birth
to_time_format :lunch_time
to_precision_number :salary, precision: 2
to_attachment :profile_picture
end
to_date_format
This shortcut adds a method to your decorator that returns the formatted date. It can accept 1 or more attributes of type Date, DateTime, or Time.
class PersonDecorator < Draper::Decorator
include DecoratorDryer
to_date_format :date_of_birth, :date_of_graduation
end
date_of_birth = Date.new(2000, 1, 1)
date_of_graduation = Date.new(2018, 6, 6)
person = Person.create(date_of_birth: date_of_birth, date_of_graduation: date_of_graduation)
person.decorate.date_of_birth # ==> '2000-01-01'
person.decorate.date_of_graduation # ==> '2018-06-06'
This shortcut uses the gem's default date format (%Y-%m-%d), or the format set in your initializer.
You could also provide a context when initializing your decorator, and tell it to return dates in a humanized format. The humanized format can also be set in your initializer.
date_of_birth = Date.new(2000, 1, 1)
person = Person.create(date_of_birth: date_of_birth)
person.decorate(context: { humanize: true }).date_of_birth # ==> '01/01/2000'
to_datetime_format
This shortcut adds a method to your decorator that returns the formatted datetime. It can accept 1 or more attributes of type DateTime or Time.
class PersonDecorator < Draper::Decorator
include DecoratorDryer
to_datetime_format :moment_of_birth, :moment_of_graduation
end
moment_of_birth = DateTime.new(2000, 1, 1, 12, 30, 59)
moment_of_graduation = DateTime.new(2018, 6, 6, 17, 00, 03)
person = Person.create(moment_of_birth: moment_of_birth, moment_of_graduation: moment_of_graduation)
person.decorate.moment_of_birth # ==> '2000-01-01 12:30'
person.decorate.moment_of_graduation # ==> '2018-06-06 17:00'
This shortcut uses the gem's default datetime format (%Y-%m-%d %H:%M), or the format set in your initializer.
You could also provide a context when initializing your decorator, and tell it to return datetimes in a humanized format. The humanized format can also be set in your initializer.
moment_of_birth = DateTime.new(2000, 1, 1, 12, 30, 59)
person = Person.create(moment_of_birth: moment_of_birth)
person.decorate(context: { humanize: true }).moment_of_birth # ==> '12:30 01/01/2000'
to_time_format
This shortcut adds a method to your decorator that returns the formatted time. It can accept 1 or more attributes of type DateTime or Time.
class PersonDecorator < Draper::Decorator
include DecoratorDryer
to_time_format :moment_of_birth, :moment_of_graduation
end
moment_of_birth = Time.new(2000, 1, 1, 12, 30, 59)
moment_of_graduation = Time.new(2018, 6, 6, 17, 00, 03)
person = Person.create(moment_of_birth: moment_of_birth, moment_of_graduation: moment_of_graduation)
person.decorate.moment_of_birth # ==> '12:30'
person.decorate.moment_of_graduation # ==> '17:00'
This shortcut uses the gem's default time format (%H:%M), or the format set in your initializer. This shortcut does not have an option for a humanized format.
to_precision_number
This shortcut adds a method to your decorator that returns the provided numbers as strings with a specific number of decimal places. It can accept 1 or more number attributes and a precision. If you would like to use different precisions for different attributes, you can use the shortcut multiple times.
class PersonDecorator < Draper::Decorator
include DecoratorDryer
to_precision_number :salary, :coffee_budget, precision: 2
to_precision_number :height_in_meters, precision: 3
end
person = Person.create(salary: 1000, coffee_budget: 20, height_in_meters: 1.8516)
person.decorate.salary # ==> '1000.00'
person.decorate.coffee_budget # ==> '20.00'
person.decorate.height_in_meters # ==> '1.852'
to_attachment
To use this shortcut, you need to enable it in your initializer (see details above).
This shortcut adds 4 methods to your decorator for each of the specified attachments. Those methods return the attachment's URL, filename, signed-id, and preview-URL.
The preview is based on the gem's default preview-transform, or the transform set in your initializer. If you would like to override the transform in your decorator, you can provide a preview_transform
option along with the attachment attributes. If you would like to use different transforms for different attributes, you can use the shortcut multiple times.
class PersonDecorator < Draper::Decorator
include DecoratorDryer
to_attachment :profile_picture, :resume
to_attachment :birth_certificate, preview_transform: :thumbnail
end
person = Person.create(profile_picture: ..., resume: ..., birth_certificate: ...)
person.decorate.profile_picture_url
person.decorate.profile_picture_name
person.decorate.profile_picture_preview
person.decorate.profile_picture_signed_id
...
Formatters
It is also possible to use the formatters directly, without the shortcuts. This gives you the flexibility to set different method names or use additional logic.
class PersonDecorator < Draper::Decorator
include DecoratorDryer
def first_birthday
format_date(object.date_of_birth)
end
def birth_datetime
format_datetime(moment_of_birth)
end
def when_is_lunch
format_time(lunch_time)
end
def income
format_precision_number(salary, precision: 2)
end
end
To Do
- Enable formats to be overridden when calling shortcuts.
- Add support for additional attachment libraries.
- Add a more flexible replacement for the
to_name
shortcut. - Add test helpers.
- Add a generator for the initialiser.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests.
To release a new version of this gem, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and the created tag, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/CodeTectonics/decorator_dryer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the DecoratorDryer project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.