https://github.com/andyw8/motion-json-decoder
Treat JSON nodes as rich objects.
https://github.com/andyw8/motion-json-decoder
Last synced: about 1 month ago
JSON representation
Treat JSON nodes as rich objects.
- Host: GitHub
- URL: https://github.com/andyw8/motion-json-decoder
- Owner: andyw8
- Created: 2013-02-20T18:44:13.000Z (about 12 years ago)
- Default Branch: master
- Last Pushed: 2013-02-21T15:50:41.000Z (about 12 years ago)
- Last Synced: 2025-03-29T05:51:15.445Z (about 2 months ago)
- Language: Ruby
- Size: 133 KB
- Stars: 10
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
motion-json-decoder
===================Treat a parsed JSON response as a graph of proper Ruby objects, rather than plain hashes and arrays.
Installation
------------
* Add `motion-json-decoder` to your Gemfile and run `bundle`.
* Add `require 'motion-json-decoder` to your Rakefile.Basic Example
-------------Let's say you have a RubyMotion app which parses this response from the server:
{
"people":
[
{
"first_name": "John",
"last_name": "Smith",
"date_of_birth": "1980-01-03"
},
{
"first_name": "Joe",
"last_name": "Bloggs",
"date_of_birth": "1967-10-11"
}
]
}i.e. a *people* collection which contains two *person* nodes.
There may be a number of place in your app where you want to display a person's full name:
names = []
json['people'].each do |person|
full_name = person['first_name'] + ' ' + person['last_name']
names << full_name
endBut doing this in multiply places isn't very DRY. You could write a helper method, but where should that code live?
*motion-json-decoder* allows the creation of mappings between the nodes in a JSON response, and simple objects. Just include the module in your class and use the simple DSL to declare your fields:
class Person
include JSONDecoder::Nodefield :first_name
field :last_namedef full_name
first_name + ' ' + last_name
end
endYou can then treat person as a simple object, by passing a hash when instantiating a new node object:
names = []
json['people'].each do |person_hash|
person = Person.new(person_hash)
NSLog "Adding #{person.first_name}..."
names << person.full_name
endExtra Protection
----------------Under the hood, motion-json-decoder uses `Hash#fetch` rather than `Hash#[]`, so if you call a field which doesn't exist, you'll get an exception right away, rather than a potentially difficult-to-debug nil return value.
Checking for Presence
---------------------
You can check if the node contains a particular key:class Person
include JSONDecoder::Nodefield :first_name
field :last_name
field :middle_name
endperson = Person.new({'first_name' => 'Andy', 'last_name' => nil})
person.first_name? #-> true
person.last_name? #-> true (even though it's nil)
person.middle_name? #-> falseCollections
------------You can specify that a nodes contains a collection of other 'resources' rather than a simple literals:
collection :organisations, :class_name -> { Organisation }
class_name parameter should be another class which includes the `JSONDecoder::Node` module.
When you call json.people, rather than array of hashes, you'll get an array of Organisation objects.
The use of the lambda (`->`) is to avoid dependency resolution problems at compile time.