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.