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

- old
+ new

@@ -7,11 +7,11 @@ 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 is almost dependency-free. Almost. +The representable gem runs with all Ruby versions >= 1.8.7. ```ruby gem 'representable' ``` @@ -231,10 +231,44 @@ property :hit, extend: SongRepresenter do property :numbers_sold end ``` +## Document Nesting + +Not always does the structure of the desired document map to your objects. The `::nested` method allows you to structure properties in a separate section while still mapping the properties to the outer object. + +Imagine the following document. + +```json +{"title": "Roxanne", + "details": + {"track": 3, + "length": "4:10"} +} +``` + +However, both `track` and `length` are properties of the song object `<Song#0x999 title: "Roxanne", track: 3 ...>`, there is no such concept as `details` in the `Song` class. Representable gives you `::nested` to achieve this. + +```ruby +class SongRepresenter < Representable::Decorator + include Representable::JSON + + property :title + + nested :details do + property :track + property :length + end +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. + + ## Decorator vs. Extend People who dislike `:extend` go use the `Decorator` strategy! ```ruby @@ -794,44 +828,47 @@ Coercing values only happens when rendering or parsing a document. Representable does not create accessors in your model as `virtus` does. ## Undocumented Features -(Please don't read this section!) +*(Please don't read this section!)* -* If you need a special binding for a property you're free to create it using the `:binding` option. +### Custom Binding -<!-- here comes some code --> +If you need a special binding for a property you're free to create it using the `:binding` option. + ```ruby property :title, :binding => lambda { |*args| JSON::TitleBinding.new(*args) } ``` -* You can use the parsed document fragment directly as a representable instance by returning `nil` in `:class`. +### Syncing Parsing -<!-- here comes some code --> +You can use the parsed document fragment directly as a representable instance by returning `nil` in `:class`. + ```ruby property :song, :class => lambda { |*| nil } ``` This makes sense when your parsing looks like this. -<!-- here comes some code --> ```ruby hit.from_hash(song: <#Song ..>) ``` Representable will not attempt to create a `Song` instance for you but use the provided from the document. -* The same goes the other way when rendering. Just provide an empty `:instance` block. +Note that this is now the [official option](#syncing-objects) `:parse_strategy`. -<!-- here comes some code --> +### Rendering Without Extend + +The same goes the other way when rendering. Just provide an empty `:instance` block. + ```ruby property :song, :instance => lambda { |*| nil } ``` This will treat the `song` property instance as a representable object. -<!-- here comes some code --> ```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.