Human Attributes
It's a Gem to convert ActiveRecord models' attributes and methods to human readable representations of these.
- Human Attributes
- Installation
- Usage
- Formatters
- Numeric
- Date
- DateTime
- Boolean
- Enumerize
- Enum
- Custom Formatter
- Common Options
- Default
- Suffix
- Multiple Formatters
- Humanize Active Record Attributes
- Integration with Draper Gem
- Rake Task
- Formatters
- Testing
- Publishing
- Contributing
- Credits
- License
Installation
Add to your Gemfile:
gem "human_attributes"bundle installUsage
Suppose you have the following model:
# == Schema Information
#
# Table name: purchases
#
# id :integer not null, primary key
# paid :boolean
# commission :decimal(, )
# quantity :integer
# state :string
# expired_at :datetime
# amount :decimal(, )
# description :text
# created_at :datetime not null
# updated_at :datetime not null
#
class Purchase < ActiveRecord::Base
extend Enumerize
STATES = %i{pending canceled finished}
enumerize :state, in: STATES, default: :pending
def commission_amount
amount * commission / 100.0
end
endExecuting the humanize method, inside the class definition, will allow you to apply Formatters to Purchase's attributes and methods.
Formatters
Numeric
With...
purchase = Purchase.new
purchase.quantity = 20
purchase.commission = 5.3And having...
class Purchase < ActiveRecord::Base
humanize :quantity, percentage: true
humanize :commission, :commission_amount, currency: { unit: "R$", separator: ",", delimiter: "" }
endYou can do...
purchase.human_quantity #=> "20.000%"
purchase.human_commission #=> "R$5,30"
purchase.human_commission_amount #=> R$1 060 000,03The available numeric types are:currency, number, size, percentage, phone, delimiter and precision.
And the options to use with numeric types, are the same as in NumberHelper
Date
With...
purchase = Purchase.new
purchase.expired_at = "04/06/1984 09:20:00"
purchase.created_at = "04/06/1984 09:20:00"
purchase.updated_at = "04/06/1984 09:20:00"And /your_app/config/locales/en.yml
en:
date:
formats:
default: "%Y-%m-%d"
short: "%b %d"And having...
class Purchase < ActiveRecord::Base
humanize :expired_at, date: { format: :short }
humanize :created_at, date: true
humanize :updated_at, date: { format: "%Y" }
endYou can do...
purchase.human_expired_at #=> "04 Jun"
purchase.human_created_at #=> "1984-06-04"
purchase.human_updated_at #=> "1984"DateTime
With...
purchase = Purchase.new
purchase.expired_at = "04/06/1984 09:20:00"
purchase.created_at = "04/06/1984 09:20:00"
purchase.updated_at = "04/06/1984 09:20:00"And /your_app/config/locales/en.yml
en:
time:
formats:
default: "%a, %d %b %Y %H:%M:%S %z"
short: "%d %b %H:%M"And having...
class Purchase < ActiveRecord::Base
humanize :expired_at, datetime: { format: :short }
humanize :created_at, datetime: true
humanize :updated_at, datetime: { format: "%Y" }
endYou can do...
purchase.human_expired_at #=> "04 Jun 09:20"
purchase.human_created_at #=> "Mon, 04 Jun 1984 09:20:00 +0000"
purchase.human_updated_at #=> "1984"Boolean
With...
purchase = Purchase.new
purchase.paid = trueAnd /your_app/config/locales/en.yml
en:
boolean:
positive: "Yes"
negative: "No"Having...
class Purchase < ActiveRecord::Base
humanize :paid, boolean: true
endYou can do...
purchase.human_paid #=> "Yes"
purchase.paid = false
purchase.human_paid #=> "No"Enumerize
Installing Enumerize gem with...
purchase = Purchase.new
purchase.state = :finishedAnd /your_app/config/locales/en.yml
en:
enumerize:
purchase:
state:
pending: "P."
finished: "F."
canceled: "C."Having...
class Purchase < ActiveRecord::Base
humanize :state, enumerize: true
endYou can do...
purchase.state = :finished
purchase.human_state #=> "F."Enum
Having...
class Purchase < ActiveRecord::Base
enum payment_method: [:credit, :debit, :cash, :bitcoin]
endYou can add
class Purchase < ActiveRecord::Base
enum payment_method: [:credit, :debit, :cash, :bitcoin]
humanize :payment_method, enum: true
endAnd /your_app/config/locales/en.yml
en:
activerecord:
attributes:
purchase:
payment_methods:
credit: "Credit Card"
debit: "Debit Card"
cash: "Cash"
bitcoin: "Bitcoin"And then you can do...
purchase = Purchase.new
purchase.payment_method = :debit
purchase.human_payment_method #=> "Debit Card"If you want to use the same enum translations for multiple models, use this locales structure:
/your_app/config/locales/en.yml
en:
enum:
default:
payment_methods:
credit: "Credit Card"
debit: "Debit Card"
cash: "Cash"
bitcoin: "Bitcoin"and then in other models will also work:
class Debt < ActiveRecord::Base
enum payment_method: [:credit, :debit, :cash, :bitcoin]
humanize :payment_method, enum: true
endpurchase = Purchase.new
purchase.payment_method = :debit
debt = Debt.new
debt.payment_method = :bitcoin
purchase.human_payment_method #=> "Debit Card"
debt.human_payment_method #=> "Bitcoin"Custom Formatter
With...
purchase = Purchase.create!And having...
class Purchase < ActiveRecord::Base
humanize :id, custom: { formatter: ->(purchase, value) { "Purchase: #{value}-#{purchase.id}" } }
endYou can do...
purchase.human_id #=> "Purchase: 1-1"Common Options
The following options are available to use with all the formatters presented before.
Default
With...
purchase = Purchase.new
purchase.amount = nilHaving...
class Purchase < ActiveRecord::Base
humanize :amount, currency: { default: 0 }
endYou can do...
purchase.human_amount #=> "$0"Suffix
Useful when you want to define multiple formatters for the same attribute.
With...
purchase = Purchase.new
purchase.paid = true
purchase.amount = 20Having...
class Purchase < ActiveRecord::Base
humanize :paid, boolean: { suffix: "with_custom_suffix" }
humanize :amount, currency: { suffix: true }
endYou can do...
purchase.paid_with_custom_suffix #=> "Yes"
purchase.amount_to_currency #=> "$20" # default suffixMultiple Formatters
With...
purchase = Purchase.new
purchase.amount = 20Having...
class Purchase < ActiveRecord::Base
humanize :amount, currency: { suffix: true }, percentage: { suffix: true }
endYou can do...
purchase.amount_to_currency #=> ""
purchase.amount_to_percentage #=> ""Remember to use
:suffixoption to avoid name collisions
Humanize Active Record Attributes
You can generate human representations for all the atributes of your ActiveRecord model like this:
class Purchase < ActiveRecord::Base
humanize_attributes
endThe humanize_attributes method will infer from the attribute's data type which formatter to choose.
With our Purchase model we will get:
purchase.human_id
purchase.human_paid
purchase.human_commission
purchase.human_quantity
purchase.human_expired_at
purchase.expired_at_to_short_date
purchase.expired_at_to_long_date
purchase.expired_at_to_short_datetime
purchase.expired_at_to_long_datetime
purchase.human_amount
purchase.human_created_at
purchase.created_at_to_short_date
purchase.created_at_to_long_date
purchase.created_at_to_short_datetime
purchase.created_at_to_long_datetime
purchase.human_updated_at
purchase.updated_at_to_short_date
purchase.updated_at_to_long_date
purchase.updated_at_to_short_datetime
purchase.updated_at_to_long_datetimeYou can pass to
humanize_attributesthe optiononly: [:attr1, :attr2]to humanize specific attributes. Theexceptoption works in similar way.
Integration with Draper Gem
If you are thinking that the formatting functionality is a view related issue, you are right. Because of this, we made the integration with Draper gem. Using draper, you can move all your humanizers to your model's decorator.
With...
class Purchase < ActiveRecord::Base
extend Enumerize
STATES = %i{pending canceled finished}
enumerize :state, in: STATES, default: :pending
humanize :state, enumerize: true
humanize :commission, percentage: true
humanize :amount, currency: true
endYou can refactor your code like this:
class Purchase < ActiveRecord::Base
extend Enumerize
STATES = %i{pending canceled finished}
enumerize :state, in: STATES, default: :pending
end
class PurchaseDecorator < Draper::Decorator
delegate_all
humanize :state, enumerize: true
humanize :commission, percentage: true
humanize :amount, currency: true
endThen, you can use it, like this:
purchase.human_amount #=> NoMethodError: undefined method `human_amount'
purchase.decorate.human_amount #=> $2,000,000.95It's not mandatory to use draper as decorator. You can extend whatever you want including HumanAttributes::Extension. For example:
Draper::Decorator.send(:include, HumanAttributes::Extension)Rake Task
You can run, from your terminal, the following task to show defined human attributes for a particular ActiveRecord model.
$ rake human_attrs:show[your-model-name]
So, with...
class Purchase < ActiveRecord::Base
extend Enumerize
STATES = %i{pending canceled finished}
enumerize :state, in: STATES, default: :pending
humanize_attributes
humanize :state, enumerize: true
humanize :commission, percentage: true
humanize :amount, currency: true
endAnd running rake human_attrs:show[purchase], you will see the following output:
human_id => Purchase: #1
human_paid => Yes
human_commission => 1000.990%
human_quantity => 1
human_expired_at => Fri, 06 Apr 1984 09:00:00 +0000
expired_at_to_short_date => Apr 06
expired_at_to_long_date => Apr 06
expired_at_to_short_datetime => 06 Apr 09:00
expired_at_to_long_datetime => 06 Apr 09:00
human_amount => $2,000,000.95
human_created_at => Sat, 10 Dec 2016 21:18:15 +0000
created_at_to_short_date => Dec 10
created_at_to_long_date => Dec 10
created_at_to_short_datetime => 10 Dec 21:18
created_at_to_long_datetime => 10 Dec 21:18
human_updated_at => Sat, 10 Dec 2016 21:18:15 +0000
updated_at_to_short_date => Dec 10
updated_at_to_long_date => Dec 10
updated_at_to_short_datetime => 10 Dec 21:18
updated_at_to_long_datetime => 10 Dec 21:18
human_state => Pending
Testing
To run the specs you need to execute, in the root path of the gem, the following command:
bundle exec guardTo run all the specs of the gem, in the root path of the gem, the following command:
bundle exec rspecYou need to put all your tests in the /human_attributes/spec/dummy/spec/ directory.
Publishing
On master/main branch...
- Change
VERSIONinlib/gemaker/version.rb. - Change
Unreleasedtitle to current version inCHANGELOG.md. - Run
bundle install. - Commit new release. For example:
Releasing v0.1.0. - Create tag. For example:
git tag v0.1.0. - Push tag. For example:
git push origin v0.1.0.
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create new Pull Request
Credits
Thank you contributors!
Human Attributes is maintained by platanus.
License
Human Attributes is © 2016 platanus, spa. It is free software and may be redistributed under the terms specified in the LICENSE file.