This library provides a framework-agnostic interface for generating HAL+JSON representations of resources in Ruby.
Add this line to your application's Gemfile:
gem'halogen'And then execute:
$ bundle Or install it yourself as:
$ gem install halogen Create a simple representer class and include Halogen:
classGoatRepresenterincludeHalogenproperty:namedo'Gideon'endlink:selfdo'/goats/gideon'endendInstantiate:
repr=GoatRepresenter.newThen call repr.render:
{name: 'Gideon',_links: {self: {href: '/goats/gideon'}}}Or repr.to_json:
'{"name": "Gideon", "_links":{"self":{"href": "/goats/gideon"}}}'Not associated with any particular resource or collection. For example, an API entry point:
classApiRootRepresenterincludeHalogenlink(:self){'/api'}endRepresents a single item:
classGoatRepresenterincludeHalogenresource:goatendWhen a resource is declared, #initialize expects the resource as the first argument:
repr=GoatRepresenter.new(Goat.new, ...)This makes property definitions cleaner:
property:name# now calls Goat#name by defaultRepresents a collection of items. When a collection is declared, the embedded resource with the same name will always be embedded, whether it is requested via standard embed options or not.
classGoatKidsRepresenterincludeHalogencollection:kidsembed(:kids){ ... }# always embeddedendProperties can be defined in several ways:
property(:age){"#{goat.age} years old"}property:age# => Goat#age, if resource is declaredproperty:agedogoat.age.roundendproperty(:age){calculate_age}defcalculate_age ... endThe inclusion of properties can be determined by conditionals using if and unless options. For example, with a method name:
property:age,if: :include_age?definclude_age?goat.age < 10endWith a proc:
property:age,unless: proc{goat.age.nil?},value: ...For links and embeds:
link:kids,:templated,unless: :exclude_kids_link?,value: ...embed:kids,if: proc{goat.kids.size > 0}do ... endSimple link:
link(:root){'/'}# =>{_links:{root:{href: '/' } } ... }Templated link:
link(:find,:templated){'/goats/{?id}'}# =>{_links:{find:{href: '/goats/{?id}', templated: true } } ... }Optional links:
representer=MyRepresenterWithManyLinks.new(include_links: false)representation=representer.renderrepresentation[:_links]#nilEmbedded resources are not rendered by default. They will be included if both of the following conditions are met:
- The proc returns either a Halogen instance or an array of Halogen instances
- The embed is requested via the parent representer's options, e.g.:
GoatRepresenter.new(embed: {kids: true,parents: false})Embedded resources can be nested to any depth, e.g.:
GoatRepresenter.new(embed: {kids: {foods: {ingredients: true},pasture: true}})If Halogen is loaded in a Rails application, Rails url helpers will be available in representers:
link(:new){new_goat_url}It is majestic.
- Fork it ( https://github.com/mode/halogen/fork )
- 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 a new Pull Request