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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 04b9042abb5650e9ee4e247e0c3539b6c5acf2f2
4
- data.tar.gz: dbf0b31e2185441e35994eb2635dc3283e301edb
3
+ metadata.gz: 24ad3203a40f611e4dd1377fec530dd5e84addcb
4
+ data.tar.gz: 5a3248058a8423c5c91b9c4a83a69a0b3616ea78
5
5
  SHA512:
6
- metadata.gz: 1baa6df02fbd4ad2e90ae39ebc36cfdf9db31f4302a0664864275b24d975c46bd9056ed9137d91fed65430a5a4e9148733dbf2e9e1aa8326653fd76e1523a2ba
7
- data.tar.gz: 902ca441b549ff9a037fd80dbf755acbf0e8309d3d198632f086d2e6cf32732244c99bdb59d098e4f65d8a31427da8505de38420ddcda9927d3a4b2e39b6292b
6
+ metadata.gz: 4aa7526345de10af58deaf60936dc9e0ed2badeffbb0e4d28bfb5bfd2547f766f5744123f2f992f39c22293e198ec0ee4f9576fbb875943f4e85d5dc5eded933
7
+ data.tar.gz: bb06e9787149d039bec360a156d770a5ab355cbb700299aa509bad05cb4f643ca3189c0449ea8283c8bce217e0b87443c43d943b3216a544a633813822f9029d
data/.travis.yml CHANGED
@@ -2,4 +2,5 @@ language: ruby
2
2
  rvm:
3
3
  - ruby-2.1.1
4
4
  - ruby-2.1.2
5
- - ruby-2.1.3
5
+ - ruby-2.1.3
6
+ - ruby-2.2.0
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
@@ -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
- self.class.injections.each do |opts|
45
- async do
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
@@ -1,3 +1,3 @@
1
1
  module Hash19
2
- VERSION = '0.0.8'
2
+ VERSION = '0.0.9'
3
3
  end
@@ -37,7 +37,7 @@ describe 'Injections' do
37
37
  ])
38
38
  end
39
39
 
40
- it "should not fail when no keys for injection present" do
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 "should only map associations with keys" do
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.8
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-05 00:00:00.000000000 Z
11
+ date: 2015-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler