hash19 0.0.8 → 0.0.9
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/.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
|