hash19 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -1
- data/README.md +2 -2
- data/lib/hash19/core.rb +0 -0
- data/lib/hash19/resolvers.rb +31 -15
- data/lib/hash19/version.rb +1 -1
- data/spec/hash19/injection_spec.rb +27 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24ad3203a40f611e4dd1377fec530dd5e84addcb
|
4
|
+
data.tar.gz: 5a3248058a8423c5c91b9c4a83a69a0b3616ea78
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4aa7526345de10af58deaf60936dc9e0ed2badeffbb0e4d28bfb5bfd2547f766f5744123f2f992f39c22293e198ec0ee4f9576fbb875943f4e85d5dc5eded933
|
7
|
+
data.tar.gz: bb06e9787149d039bec360a156d770a5ab355cbb700299aa509bad05cb4f643ca3189c0449ea8283c8bce217e0b87443c43d943b3216a544a633813822f9029d
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -198,9 +198,9 @@ super_heroes.to_h #[{'name' => 'iron man', 'power' => 'none', 'weapon' => {'name
|
|
198
198
|
#{'name' => 'hulk', 'power' => 'bulk', 'weapon' => {'name' => 'hands', 'id' => 3}}
|
199
199
|
```
|
200
200
|
|
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.
|
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.
|
202
202
|
|
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.
|
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. If one inject is dependent on another or if you want the injections to happen in sequence add `async: false` to make calls synchronously.
|
204
204
|
|
205
205
|
Please refer to the [tests](https://github.com/rcdexta/hash19/tree/master/spec/hash19) for more examples and documentation.
|
206
206
|
|
data/lib/hash19/core.rb
CHANGED
File without changes
|
data/lib/hash19/resolvers.rb
CHANGED
@@ -27,7 +27,7 @@ module Hash19
|
|
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]
|
29
29
|
if opts[:trigger] and @hash19.has_key? opts[:using]
|
30
|
-
@hash19[opts[:alias] || name] = LazyValue.new(-> { opts[:trigger].call(@hash19.delete(opts[:using])) })
|
30
|
+
@hash19[opts[:alias] || name] = LazyValue.new(-> { opts[:trigger].call(@hash19.delete(opts[:using])) })
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -41,22 +41,11 @@ module Hash19
|
|
41
41
|
|
42
42
|
def resolve_injections(hash)
|
43
43
|
together do
|
44
|
-
|
45
|
-
async
|
46
|
-
entries = JsonPath.new(opts[:at]).on(hash).flatten
|
47
|
-
ids = entries.map { |el| el[opts[:using]] }.compact
|
48
|
-
next unless ids.present?
|
49
|
-
to_inject = opts[:trigger].call(ids).map(&:with_indifferent_access)
|
50
|
-
key = opts[:as] || opts[:using].to_s.gsub(/_id$|Id$/, '')
|
51
|
-
entries.each do |entry|
|
52
|
-
id = entry.delete(opts[:using])
|
53
|
-
next unless id.present?
|
54
|
-
target = to_inject.find { |el| el[opts[:reference] || opts[:using]] == id }
|
55
|
-
entry[key] = target
|
56
|
-
end
|
57
|
-
end
|
44
|
+
async_injections.each do |opts|
|
45
|
+
async { call_and_inject(opts, hash) }
|
58
46
|
end
|
59
47
|
end
|
48
|
+
synchronous_injections.each { |opts| call_and_inject(opts, hash) }
|
60
49
|
end
|
61
50
|
|
62
51
|
def resolve_class(assoc_name)
|
@@ -71,5 +60,32 @@ module Hash19
|
|
71
60
|
end
|
72
61
|
end
|
73
62
|
|
63
|
+
private
|
64
|
+
|
65
|
+
def async_injections
|
66
|
+
self.class.injections.select { |e| e[:async].nil? }
|
67
|
+
end
|
68
|
+
|
69
|
+
def synchronous_injections
|
70
|
+
self.class.injections.select { |e| e[:async] == false }
|
71
|
+
end
|
72
|
+
|
73
|
+
def call_and_inject(opts, hash)
|
74
|
+
entries = JsonPath.new(opts[:at]).on(hash).flatten
|
75
|
+
ids = entries.map { |el| el[opts[:using]] }.compact
|
76
|
+
return unless ids.present?
|
77
|
+
to_inject = opts[:trigger].call(ids).map(&:with_indifferent_access)
|
78
|
+
key = opts[:as] || opts[:using].to_s.gsub(/_id$|Id$/, '')
|
79
|
+
entries.each do |entry|
|
80
|
+
id = entry[opts[:using]]
|
81
|
+
next unless id.present?
|
82
|
+
target = to_inject.find { |el| el[opts[:reference] || opts[:using]] == id }
|
83
|
+
if target
|
84
|
+
entry.delete(opts[:using])
|
85
|
+
entry[key] = target
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
74
90
|
end
|
75
91
|
end
|
data/lib/hash19/version.rb
CHANGED
@@ -37,7 +37,7 @@ describe 'Injections' do
|
|
37
37
|
])
|
38
38
|
end
|
39
39
|
|
40
|
-
it
|
40
|
+
it 'should not fail when no keys for injection present' do
|
41
41
|
gru_team = SuperVillain.new(name: 'Gru', minions: [{name: 'Poppadom'},
|
42
42
|
{name: 'Gelato'},
|
43
43
|
{name: 'Kanpai'}])
|
@@ -47,7 +47,7 @@ describe 'Injections' do
|
|
47
47
|
])
|
48
48
|
end
|
49
49
|
|
50
|
-
it
|
50
|
+
it 'should only map associations with keys' do
|
51
51
|
gru_team = SuperVillain.new(name: 'Gru', minions: [{name: 'Poppadom', fruit_id: 1},
|
52
52
|
{name: 'Gelato'},
|
53
53
|
{name: 'Kanpai'}])
|
@@ -57,6 +57,31 @@ describe 'Injections' do
|
|
57
57
|
])
|
58
58
|
end
|
59
59
|
|
60
|
+
class SuperDuperVillain < Testable
|
61
|
+
attribute :name
|
62
|
+
has_many :minions
|
63
|
+
inject at: '$.minions', using: :fruit_id, reference: :id, trigger: lambda { |ids| Fruit.find_all ids }, as: 'eats'
|
64
|
+
inject at: '$.minions..eats', using: :name, reference: :fruit_name, trigger: lambda { |names| Vitamin.find_all names }, as: 'vitamin', async: false
|
65
|
+
end
|
66
|
+
|
67
|
+
class Vitamin < Testable
|
68
|
+
attributes :has, :fruit_name
|
69
|
+
|
70
|
+
def self.find_all(names)
|
71
|
+
[{fruit_name: 'banana', has: 'D'}, {fruit_name: 'orange', has: 'E'}]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should be to do injections synchronously' do
|
76
|
+
gru_team = SuperDuperVillain.new(name: 'Gru', minions: [{name: 'Poppadom', fruit_id: 1},
|
77
|
+
{name: 'Gelato', fruit_id: 2},
|
78
|
+
{name: 'Kanpai', fruit_id: 3}])
|
79
|
+
expect(gru_team.to_h).to eq('name' => 'Gru', 'minions' => [{'name' => 'Poppadom', 'eats' => {'id' => 1, 'vitamin' => {'fruit_name' => 'banana', 'has' => 'D'}}},
|
80
|
+
{'name' => 'Gelato', 'eats' => {'id' => 2, 'name' => 'apple'}},
|
81
|
+
{'name' => 'Kanpai', 'eats' => {'id' => 3, 'vitamin' => {'fruit_name' => 'orange', 'has' => 'E'}}}
|
82
|
+
])
|
83
|
+
end
|
84
|
+
|
60
85
|
end
|
61
86
|
|
62
87
|
end
|
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.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- RC
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|