README.md in representable-1.7.6 vs README.md in representable-1.7.7

- old
+ new

@@ -1,12 +1,12 @@ # Representable -Representable maps ruby objects to documents and back. +Representable maps Ruby objects to documents and back. In other words: Take an object and decorate it with a representer module. This will allow you to render a JSON, XML or YAML document from that object. But that's only half of it! You can also use representers to parse a document and create or populate an object. -Representable is helpful for all kind of rendering and parsing workflows. However, it is mostly useful in API code. Are you planning to write a real REST API with representable? Then check out the [roar](http://github.com/apotonick/roar) gem first, save work and time and make the world a better place instead. +Representable is helpful for all kind of rendering and parsing workflows. However, it is mostly useful in API code. Are you planning to write a real REST API with representable? Then check out the [Roar](http://github.com/apotonick/roar) gem first, save work and time and make the world a better place instead. ## Installation The representable gem runs with all Ruby versions >= 1.8.7. @@ -262,11 +262,11 @@ end ``` Just use an inline representer or the `extend:` option to define nested properties. Accessors for nested properties will still be called on the outer object (here, `song`). And as always, this works both ways for rendering and parsing. -Note that `nested` works with decorators, only. We might add it for modules soon. +Note that `::nested` internally is implemented using `Decorator`. When adding methods inside the `nested` block, make sure to use `represented` (`self` will point to the decorator instance). ## Decorator vs. Extend People who dislike `:extend` go use the `Decorator` strategy! @@ -450,10 +450,19 @@ extend(CoverSongRepresenter).to_json #=> {"title":"Truth Hits Everybody","copyright":"The Police"} ``` +With decorators, you - surprisingly - use class inheritance. + +```ruby +class HitRepresenter < SongRepresenter + collection :airplays +``` + + + ## Overriding Properties You might want to override a particular property in an inheriting representer. Successively calling `property(name)` will override the former definition for `name` just as you know it from overriding methods. ```ruby @@ -466,10 +475,94 @@ ``` This behaviour was added in 1.7. +## Partly Overriding Properties + +If you wanna override only certain options of the property, use `:inherit`. + +```ruby +module SongRepresenter + include Representable::JSON + + property :title, as: :known_as +end +``` + +You can now inherit but still override or add options. + +```ruby +module CoverSongRepresenter + include Representable::JSON + include SongRepresenter + + property :title, getter: lambda { Title.random }, inherit: true +end +``` + +This will result in a property having the following options. + +```ruby + property :title, + as: :known_as, # inherited from SongRepresenter + getter: lambda { .. } # added in inheriting representer. +end +``` + +## Inheritance With Inline Representers + +Inheriting also works for inline representers. + +```ruby +module SongRepresenter + include Representable::JSON + + property :title + property :label do + property :name + end +end +``` + +You can now override or add properties with the inline representer. + +```ruby +module HitRepresenter + include Representable::JSON + include SongRepresenter + + property :label, inherit: true do + property :country + end +end +``` + +Results in a combined inline representer as it inherits. + +```ruby +property :label do + property :name + property :country +end +``` + +Note that the following also works. + +```ruby +module HitRepresenter + include Representable::JSON + include SongRepresenter + + property :label, as: :company, inherit: true +end +``` + +This renames the property but still inherits all the inlined configuration. + +Basically, `:inherit` copies the configuration from the parent property, then merges it your options from the inheriting representer. It exposes the same behaviour as `super` in Ruby - when using `:inherit` the property must exist in the parent representer. + ## Polymorphic Extend Sometimes heterogenous collections of objects from different classes must be represented. Or you don't know which representer to use at compile-time and need to delay the computation until runtime. This is why `:extend` accepts a lambda, too. Given we not only have songs, but also cover songs. @@ -871,9 +964,19 @@ ```ruby hit.to_json # this will call hit.song.to_json ``` Rendering `collection`s works the same. Parsing doesn't work out-of-the-box, currently, as we're still unsure how to map items to fragments. + +### Decorator In Module + +Inline representers defined in a module can be implemented as a decorator, thus wrapping the represented object without pollution. + +```ruby +property :label, decorator: true do + ... +end +``` ## Copyright Representable started as a heavily simplified fork of the ROXML gem. Big thanks to Ben Woosley for his inspiring work.