README.md in representable-1.3.4 vs README.md in representable-1.3.5
- old
+ new
@@ -63,11 +63,11 @@
include Representable::JSON
property :title, as: :name
property :track
end
-
+
song.to_json #=> {"name":"Fallout","track":1}
## Wrapping
@@ -205,11 +205,11 @@
Sometimes it's useful to override accessors to customize output or parsing.
module AlbumRepresenter
include Representable::JSON
-
+
property :name
collection :songs
def name
super.upcase
@@ -258,13 +258,13 @@
class CoverSong < Song
end
And a non-homogenous collection of songs.
- songs = [ Song.new(title: "Weirdo", track: 5),
+ songs = [ Song.new(title: "Weirdo", track: 5),
CoverSong.new(title: "Truth Hits Everybody", track: 6, copyright: "The Police")]
-
+
album = Album.new(name: "Incognito", songs: songs)
The `CoverSong` instances are to be represented by their very own `CoverSongRepresenter` defined above. We can't just use a static module in the `:extend` option, so go use a dynamic lambda!
@@ -284,11 +284,11 @@
module AlbumRepresenter
include Representable::JSON
property :name
- collection :songs,
+ collection :songs,
:extend => ...,
:class => lambda { |hsh| hsh.has_key?("copyright") ? CoverSong : Song }
end
The block for `:class` receives the currently parsed fragment. Here, this might be somthing like `{"title"=>"Weirdo", "track"=>5}`.
@@ -297,30 +297,30 @@
module AlbumRepresenter
include Representable::JSON
property :name
- collection :songs,
+ collection :songs,
:extend => ...,
:instance => lambda { |hsh| hsh.has_key?("copyright") ? CoverSong.new : Song.new(original: true) }
end
## Hashes
As an addition to single properties and collections representable also offers to represent hash attributes.
-
+
module SongRepresenter
include Representable::JSON
property :title
hash :ratings
end
Song.new(title: "Bliss", ratings: {"Rolling Stone" => 4.9, "FryZine" => 4.5}).
extend(SongRepresenter).to_json
-
+
#=> {"title":"Bliss","ratings":{"Rolling Stone":4.9,"FryZine":4.5}}
## Lonely Hashes
@@ -398,11 +398,11 @@
include Representable::XML
property :title, attribute: true
property :track, attribute: true
end
-
+
Song.new(title: "American Idle").to_xml
#=> <song title="American Idle" />
Naturally, this works for both ways.
@@ -416,11 +416,11 @@
collection :songs, :as => :song, :wrap => :songs
end
Note that `:wrap` defines the container tag name.
- Album.new.to_xml #=>
+ Album.new.to_xml #=>
<album>
<songs>
<song>Laundry Basket</song>
<song>Two Kevins</song>
<song>Wright and Rong</song>
@@ -443,10 +443,23 @@
## More Options
Here's a quick overview about other available options for `#property` and its bro `#collection`.
+
+### Overriding Read And Write
+
+This can be handy if a property needs to be compiled from several fragments. The lambda has access to the entire object document (either hash or `Nokogiri` node) and user options.
+
+ property :title, :writer => lambda { |doc, args| doc["title"] = title || original_title }
+
+When using the `:writer` option it is up to you to add fragments to the `doc` - representable won't add anything for this property.
+
+The same works for parsing using `:reader`.
+
+ property :title, :reader => lambda { |doc, args| self.title = doc["title"] || doc["name"] }
+
### Read/Write Restrictions
Using the `:readable` and `:writeable` options access to properties can be restricted.
property :title, :readable => false
@@ -470,11 +483,11 @@
include Representable::JSON
property :title
property :track, if: lambda { track > 0 }
end
-
+
When rendering or parsing, the `track` property is considered only if track is valid. Note that the block is executed in instance context, giving you access to instance methods.
As always, the block retrieves your options. Given this render call
song.to_json(minimum_track: 2)
@@ -503,10 +516,10 @@
Use the `:type` option to specify the conversion target. Note that `:default` still works.
module SongRepresenter
include Representable::JSON
include Representable::Coercion
-
+
property :title
property :recorded_at, :type => DateTime, :default => "May 12th, 2012"
end