NOTE: LazyDoc is currently in alpha and is not quite ready for use.
An implementation of the Embedded Document pattern for POROs.
LazyDoc provides a declarative DSL for extracting deeply nested values from a JSON document. The embedded JSON is lazily parsed so that needed attributes from the document are only parsed when accessed. Finally, parsed values are cached so that subsequent access does not access the JSON again.
Currently, LazyDoc only supports JSON. XML support will be added later.
Add this line to your application's Gemfile:
gem 'lazy_doc'
- Basic usage.
access :namewill look for a property called 'name' at the top level of the embedded document. via:access :job, via: [:profile, :occupation]will look for a property called 'job' by parsing through 'profile' -> 'occupation'.finally:access :initials, finally: lambda { |initials| initials.upcase }will call the supplied block, passing in 'initials,' and will return the result of that block.as:access :profile, as: Profilewill pass the sub-document found at 'profile' into a new 'Profile' object, and will return the newly constructed Profile object. This is great for constructing nested LazyDoc relationships.
class User
include LazyDoc::DSL
access :name # Access the attribute "name"
access :address, via: :street_address # Access the attribute "street_address"
access :job, via: [:profile, :occupation, :title] # Access the attribute "title" found at "profile" -> "occupation"
def initialize(json)
lazily_embed(json) # Initialize the LazyDoc object
end
end
user = User.new(json)
puts user.name
puts user.address
puts user.job- DONE - Full path parsing more than just top level. ex:
access :name, by: [:profile, :basic_info, :name] - Error handling for incorrectly specified paths
- Exception handling when a json does not contain a path, but that is ok.
- DONE - Transforms. ex:
access :name, finally: lambda { |name| name.gsub('-',' ') } - DONE - Objects from sub-trees. ex:
access :profile, as: Profile(This would construct a LazyDoc Profile object and pass the json found at "profile" to it) - Collections.
- Map. For example, extract array of customer names from array of customers. ex:
access :customers, extract: :name - Objects from collection. Instead of extracting just the name, extract whole objects like in #5. ex:
access :customers, as: Customer
- Map. For example, extract array of customer names from array of customers. ex:
- Joins
- Using previously defined attributes. ex:
join :address, from: [:street, :city, :state:, :zip] - Defining attributes in place.
- Using previously defined attributes. ex:
- Throw exception immediately when trying to use incompatible options (ex:
'finally' and 'as') - Multiple simple paths in one line (ex:
access :name, :street, :city, :state) - XML support
- Fork it
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Added some feature') - Push to the branch (
git push origin my-new-feature) - Create new Pull Request