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