hash19 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +0 -0
- data/.ruby-gemset +0 -0
- data/.ruby-version +0 -0
- data/.travis.yml +1 -1
- data/Gemfile +0 -0
- data/LICENSE.txt +0 -0
- data/README.md +19 -7
- data/Rakefile +0 -0
- data/hash19.gemspec +1 -0
- data/lib/hash19/core.rb +2 -2
- data/lib/hash19/core_helpers.rb +0 -0
- data/lib/hash19/lazy_value.rb +0 -0
- data/lib/hash19/resolvers.rb +3 -3
- data/lib/hash19/version.rb +1 -1
- data/lib/hash19.rb +0 -0
- data/spec/hash19/access_spec.rb +0 -0
- data/spec/hash19/associations_spec.rb +0 -0
- data/spec/hash19/contains_spec.rb +0 -0
- data/spec/hash19/core_spec.rb +0 -0
- data/spec/hash19/future_spec.rb +0 -0
- data/spec/hash19/injection_spec.rb +0 -0
- data/spec/spec_helper.rb +2 -0
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04b9042abb5650e9ee4e247e0c3539b6c5acf2f2
|
4
|
+
data.tar.gz: dbf0b31e2185441e35994eb2635dc3283e301edb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1baa6df02fbd4ad2e90ae39ebc36cfdf9db31f4302a0664864275b24d975c46bd9056ed9137d91fed65430a5a4e9148733dbf2e9e1aa8326653fd76e1523a2ba
|
7
|
+
data.tar.gz: 902ca441b549ff9a037fd80dbf755acbf0e8309d3d198632f086d2e6cf32732244c99bdb59d098e4f65d8a31427da8505de38420ddcda9927d3a4b2e39b6292b
|
data/.gitignore
CHANGED
File without changes
|
data/.ruby-gemset
CHANGED
File without changes
|
data/.ruby-version
CHANGED
File without changes
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
File without changes
|
data/LICENSE.txt
CHANGED
File without changes
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Hash19
|
2
2
|
[](https://travis-ci.org/rcdexta/hash19)
|
3
|
+
[](http://badge.fury.io/rb/hash19)
|
4
|
+
[](https://coveralls.io/r/rcdexta/hash19)
|
3
5
|
|
4
6
|

|
5
7
|
|
@@ -7,6 +9,8 @@
|
|
7
9
|
|
8
10
|
Ahem.. Ahem.. So about this gem itself.. When I was writing an aggregation API that had to talk to multiple services each with their own REST end-points and JSON schema, when mashing up multiple hashes and transforming it to a structure acceptable to the consumer, I ended up writing lot of boiler plate code. I could see patterns and there was clearly scope for optimisation.
|
9
11
|
|
12
|
+
A [detailed writeup](https://medium.com/@rcdexta/hash19-a-json-aggregation-library-f2ef43d64a86) explaining the need is available for reading.
|
13
|
+
|
10
14
|
Hash19 is an attempt at offering a DSL to tame the JSON manipulation and help in dealing with common use-cases. The features include
|
11
15
|
|
12
16
|
* whitelisting attributes
|
@@ -150,9 +154,17 @@ end
|
|
150
154
|
```
|
151
155
|
If you notice the trigger, the `using` parameter denotes the attribute to use to fetch the association and the lambda passed to `trigger` will be invoked to fetch the association. This is lazy loaded, in the sense when a call is made to `.doctor` or `.to_h`, the trigger is fired.
|
152
156
|
|
157
|
+
Associations also support alternate keys and aliasing... The below code snippet illustrates use of a different key in source json, the class to use to construct the object and the alias key in the target.
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
has_one :child, key: :offspring, alias: :junior
|
161
|
+
{offspring: {name: 'Luke Skywalker'}} # will be parsed as {'junior' => {'name' => 'Luke Skywalker'}}
|
162
|
+
```
|
163
|
+
|
164
|
+
|
153
165
|
###4. Bulk Injections
|
154
166
|
|
155
|
-
Left to itself with associations, when the root JSON is a large collection with none of the associations populated in the first place, there will several triggers fired for each item in the collection. This is the HTTP equivalent of `N+1` in the ORM world. To avoid this, Hash19 supports association injections. Let's dive into an example:
|
167
|
+
Left to itself with associations, when the root JSON is a large collection with none of the associations populated in the first place, there will be several triggers fired for each item in the collection. This is the HTTP equivalent of `N+1` in the ORM world. To avoid this, Hash19 supports association injections. Let's dive into an example:
|
156
168
|
|
157
169
|
```ruby
|
158
170
|
class SuperHeroes < Hashable
|
@@ -170,13 +182,13 @@ class SuperHeroes < Hashable
|
|
170
182
|
def find_all(ids)..end #calls bulk API across wire. Implementation hidden
|
171
183
|
end
|
172
184
|
```
|
173
|
-
If you notice, `SuperHeroes` is a wrapper class around `SuperHero`. This is the object equivalent of a JSON collection. The `inject` method will extract `weapon_id` from all items in the collection and call the `trigger` and put back the resultant entities joining `superhero.weapon_id` and `weapon.id`
|
185
|
+
If you notice, `SuperHeroes` is a wrapper class around `SuperHero`. This is the object equivalent of a JSON collection. The `inject` method will extract `weapon_id` from all items in the collection based on the json-path specified by `at` and call the `trigger` and put back the resultant entities joining `superhero.weapon_id` and `weapon.id`
|
174
186
|
|
175
187
|
So, a json like below
|
176
|
-
```
|
177
|
-
|
178
|
-
|
179
|
-
|
188
|
+
```ruby
|
189
|
+
super_heros = SuperHeroes.new([{name: 'iron man', power: 'none', weapon_id: 1},
|
190
|
+
{name: 'thor', power: 'class 100', weapon_id: 2},
|
191
|
+
{name: 'hulk', power: 'bulk', weapon_id: 3}])
|
180
192
|
```
|
181
193
|
|
182
194
|
will lead to one call to `Weapon#find_all` with params `[1,2,3]` to fetch all weapon details. And the final collection will be of the form:
|
@@ -186,7 +198,7 @@ super_heroes.to_h #[{'name' => 'iron man', 'power' => 'none', 'weapon' => {'name
|
|
186
198
|
#{'name' => 'hulk', 'power' => 'bulk', 'weapon' => {'name' => 'hands', 'id' => 3}}
|
187
199
|
```
|
188
200
|
|
189
|
-
Note that `injection` always overrides the association trigger
|
201
|
+
Note that `injection` always overrides the association trigger since the former is eager loaded and latter is lazy loaded thus avoiding the `N+1` calls.
|
190
202
|
|
191
203
|
One other important thing to remember is that all the injections will happen in parallel. Hash19 uses [eldritch](https://github.com/beraboris/eldritch) gem to trigger multiple injections concurrently.
|
192
204
|
|
data/Rakefile
CHANGED
File without changes
|
data/hash19.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency 'rspec'
|
24
24
|
spec.add_development_dependency 'pry'
|
25
25
|
spec.add_development_dependency 'rake'
|
26
|
+
spec.add_development_dependency 'coveralls'
|
26
27
|
|
27
28
|
spec.add_runtime_dependency 'jsonpath', '~> 0.5.6'
|
28
29
|
spec.add_runtime_dependency 'eldritch'
|
data/lib/hash19/core.rb
CHANGED
@@ -14,7 +14,7 @@ module Hash19
|
|
14
14
|
if payload.is_a? Array
|
15
15
|
@hash19 = payload.map do |el|
|
16
16
|
klass = resolve_class(self.class.contains_klass.to_s.camelize.singularize)
|
17
|
-
klass.send(:new, el).to_h(
|
17
|
+
klass.send(:new, el).to_h(true)
|
18
18
|
end
|
19
19
|
else
|
20
20
|
hash = payload.with_indifferent_access
|
@@ -39,7 +39,7 @@ module Hash19
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
def to_h(lazy
|
42
|
+
def to_h(lazy=false)
|
43
43
|
return @hash19 if lazy
|
44
44
|
if @hash19.is_a? Array
|
45
45
|
@hash19.map { |hash| traverse_hash(hash) }
|
data/lib/hash19/core_helpers.rb
CHANGED
File without changes
|
data/lib/hash19/lazy_value.rb
CHANGED
File without changes
|
data/lib/hash19/resolvers.rb
CHANGED
@@ -16,13 +16,13 @@ module Hash19
|
|
16
16
|
if association.present?
|
17
17
|
klass = resolve_class(class_name.singularize)
|
18
18
|
@hash19[opts[:alias] || name] = if type == :one
|
19
|
-
klass.send(:new, association).to_h(
|
19
|
+
klass.send(:new, association).to_h(true)
|
20
20
|
elsif type == :many
|
21
|
-
association.map { |hash| klass.send(:new, hash).to_h(
|
21
|
+
association.map { |hash| klass.send(:new, hash).to_h(true) }
|
22
22
|
end
|
23
23
|
else
|
24
24
|
unless opts[:trigger]
|
25
|
-
puts "warning: Association:<#{name}> is not present in #{self.class.name}.
|
25
|
+
# puts "warning: Association:<#{name}> is not present in #{self.class.name}. Probably a trigger is missing!"
|
26
26
|
next
|
27
27
|
end
|
28
28
|
puts "warning: Key:<#{opts[:using]}> not present in #{self.class.name}. Cannot map association:<#{name}>" unless @hash19.has_key? opts[:using]
|
data/lib/hash19/version.rb
CHANGED
data/lib/hash19.rb
CHANGED
File without changes
|
data/spec/hash19/access_spec.rb
CHANGED
File without changes
|
File without changes
|
File without changes
|
data/spec/hash19/core_spec.rb
CHANGED
File without changes
|
data/spec/hash19/future_spec.rb
CHANGED
File without changes
|
File without changes
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hash19
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- RC
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: coveralls
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: jsonpath
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -158,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
172
|
version: '0'
|
159
173
|
requirements: []
|
160
174
|
rubyforge_project:
|
161
|
-
rubygems_version: 2.
|
175
|
+
rubygems_version: 2.4.5
|
162
176
|
signing_key:
|
163
177
|
specification_version: 4
|
164
178
|
summary: Hash helpers to map complex JSON to ruby objects. Handles associations and
|