unique_by 2.0.0 → 2.1.0

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: 4839ad7e8c93eabad52a34ae43774c3a4fa31ead
4
- data.tar.gz: d205bd87ab905c57bbc620df6400a36fe9c95fba
3
+ metadata.gz: 5403c00bf28bbe7858fa14d407bdbda99527de7e
4
+ data.tar.gz: e9e0dcd9a442febb74ffd046edda31edfc9f4f9d
5
5
  SHA512:
6
- metadata.gz: afe1110aa03ea678e269655cbbd8d10ff7cbca5406b62a5193724f5617789db734d93e033a56d6077611e3ef9c54ead59dc5a1f80035c74a73ccbcf29cd5deba
7
- data.tar.gz: fe7ac2951507f1b2a709f905469881f3e29b4c67d3c1a110b3bd8448d82d869932a13a3758c9de217121b296e989ee50366b17f2cea089ef35deeb1b5babefa4
6
+ metadata.gz: 2d4d75f32cde147d62e1c6e0a51580c0e4d339fa964d0675413562415ae58b49c650cf5752428d1d164d16e1576d88950b7d7e04d260ef0d2b6be16b8a9a1bce
7
+ data.tar.gz: ec47fa855292e7e207ada64eb92f54852c114578297a68adedf5895edb0b35d7f5b68171a6a2c94b1a894f77e70484e14af4ed5304d61dcb56b3e9cdf4dc1375
data/README.md CHANGED
@@ -54,10 +54,6 @@ bill1.unique_id
54
54
  => 7873
55
55
  bill2.unique_id
56
56
  => 7874
57
- MedicalBill.find_by_unique_id(7873) # from DB shard for client_id = 1
58
- => #<MedicalBill id: 123, client_id: 1>
59
- MedicalBill.find_by_unique_id(7874) # from DB shard for client_id = 2
60
- => #<MedicalBill id: 123, client_id: 2>
61
57
  ```
62
58
 
63
59
  You can use the internal methods:
@@ -79,6 +75,21 @@ class MedicalBill < ActiveRecord::Base
79
75
  end
80
76
  ```
81
77
 
78
+ It is recommended to create finder methods that will find records according to
79
+ their id group, like so:
80
+
81
+ ```ruby
82
+ class MedicallBill < ActiveRecord::Base
83
+ unique_by client_id: 50, client_part: 5 # total of 50 clients and 5 parts
84
+
85
+ def self.find_by_unique_id(unique_id)
86
+ withing_client_connection(id_group_from(unique_id)[:client_id]) do
87
+ find(id_from(unique_id))
88
+ end
89
+ end
90
+ end
91
+ ```
92
+
82
93
  ### Multiple tables example
83
94
 
84
95
  You can supply a block to give a custom mechanism for determining the group:
@@ -103,6 +114,21 @@ class MedicalBill < ActiveRecord::Base
103
114
  end
104
115
  ```
105
116
 
117
+ It is recommended to create finder methods that will find records according to
118
+ their id group, like so:
119
+
120
+ ```ruby
121
+ module Bill
122
+ module_function
123
+ def find_by_unique_id(unique_id)
124
+ case MedicalBill.id_group_from(unique_id)[:type]
125
+ when 1 then MedicalBill.find(MedicalBill.id_from(unique_id))
126
+ when 2 then UtilityBill.find(UtilityBill.id_from(unique_id))
127
+ end
128
+ end
129
+ end
130
+ ```
131
+
106
132
  ## Not ActiveRecord
107
133
 
108
134
  The generator module is already included in `ActiveRecord::Base`, but if
@@ -127,14 +153,14 @@ fix that:
127
153
  ```ruby
128
154
  class MedicalBill < ActiveRecord::Base
129
155
  unique_by client_id: 500
130
- rebase_attr :unique_id, to: 32, readable: true
156
+ rebase_attr :unique_id, to: 32, readable: true # digits and leters, without '0', 'o', '1' and 'l'
131
157
  end
132
158
 
133
- bill = MedicalBill.find(3528918) # from a DB shard for client_id = 1
159
+ bill = MedicalBill.find(3528918) # from a DB shard for client_id = 78
134
160
  bill.unique_id
135
- => "ywr3bxx"
136
- MedicalBill.find_by_unique_id(MedicalBill.decode_unique_id("ywr3bxx"))
137
- => #<MedicalBill id: 3528918, client_id: 1>
161
+ => "ywr3b2e"
162
+ bill.unique_id_without_rebase
163
+ => 1806806094
138
164
  ```
139
165
 
140
166
  ## Contributing
@@ -1,3 +1,3 @@
1
1
  module UniqueBy
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
data/lib/unique_by.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "unique_by/version"
2
+ require "generate_method"
2
3
 
3
4
  module UniqueBy
4
5
  module Generator
@@ -20,56 +21,52 @@ module UniqueBy
20
21
 
21
22
  pk = primary_key # converting to a local variable
22
23
 
23
- define_singleton_method :"#{pk}_group_value_from" do |**group|
24
- raise ArgumentError, "unknown #{pk} group keys: #{group.keys - group_totals.keys}" if (group.keys - group_totals.keys).any?
25
- raise ArgumentError, "missing #{pk} group keys: #{group_totals.keys - group.keys}" if (group_totals.keys - group.keys).any?
26
- group_totals.keys.reduce(0) do |group_value, group_name|
27
- g = group[group_name]
28
- raise TypeError, "#{pk} group #{group_name} must not be nil" if g.nil?
29
- raise TypeError, "#{pk} group #{group_name} must implement #to_i, #{g.inspect} given" unless g.respond_to?(:to_i)
30
- (group_value << bits[group_name]) + (g.to_i % totals[group_name])
24
+ generate_singleton_methods do
25
+ define_method :"#{pk}_group_value_from" do |**group|
26
+ raise ArgumentError, "unknown #{pk} group keys: #{group.keys - group_totals.keys}" if (group.keys - group_totals.keys).any?
27
+ raise ArgumentError, "missing #{pk} group keys: #{group_totals.keys - group.keys}" if (group_totals.keys - group.keys).any?
28
+ group_totals.keys.reduce(0) do |group_value, group_name|
29
+ g = group[group_name]
30
+ raise TypeError, "#{pk} group #{group_name} must not be nil" if g.nil?
31
+ raise TypeError, "#{pk} group #{group_name} must implement #to_i, #{g.inspect} given" unless g.respond_to?(:to_i)
32
+ (group_value << bits[group_name]) + (g.to_i % totals[group_name])
33
+ end
31
34
  end
32
- end
33
-
34
- define_singleton_method :"unique_#{pk}_from" do |id, **group|
35
- break nil if id.nil?
36
- raise TypeError, "#{pk} must implement #to_i, #{id.inspect} given" unless id.respond_to?(:to_i)
37
- (id.to_i << bits.values.inject(&:+)) + send(:"#{pk}_group_value_from", **group)
38
- end
39
35
 
40
- define_singleton_method :"#{pk}_from" do |unique_id|
41
- break nil if unique_id.nil?
42
- raise TypeError, "unique_#{pk} must implement #to_i, #{unique_id.inspect} given" unless unique_id.respond_to?(:to_i)
43
- unique_id.to_i >> bits.values.inject(&:+)
44
- end
45
-
46
- define_singleton_method :"#{pk}_group_from" do |unique_id|
47
- break nil if unique_id.nil?
48
- raise TypeError, "unique_#{pk} must implement #to_i, #{unique_id.inspect} given" unless unique_id.respond_to?(:to_i)
49
- Hash[group_totals.keys.reverse.map do |group_name|
50
- g = unique_id & (totals[group_name] - 1)
51
- unique_id >>= bits[group_name]
52
- [group_name, g]
53
- end.reverse]
54
- end
36
+ define_method :"unique_#{pk}_from" do |id, **group|
37
+ break nil if id.nil?
38
+ raise TypeError, "#{pk} must implement #to_i, #{id.inspect} given" unless id.respond_to?(:to_i)
39
+ (id.to_i << bits.values.inject(&:+)) + send(:"#{pk}_group_value_from", **group)
40
+ end
55
41
 
56
- define_method :"#{pk}_group" do
57
- group_from_block = group_block ? instance_eval(&group_block) : {}
58
- raise TypeError, "#{pk} group block must return a Hash with any of the following keys: #{group_totals.keys}, #{group_from_block.inspect} given" unless group_from_block.is_a?(Hash)
59
- raise ArgumentError, "unknown #{pk} group passed to block: #{group_from_block.keys - group_totals.keys}" if (group_from_block.keys - group_totals.keys).any?
60
- Hash[(group_totals.keys - group_from_block.keys).map { |group_name| [group_name, send(group_name)] }].merge(group_from_block)
61
- end
42
+ define_method :"#{pk}_from" do |unique_id|
43
+ break nil if unique_id.nil?
44
+ raise TypeError, "unique_#{pk} must implement #to_i, #{unique_id.inspect} given" unless unique_id.respond_to?(:to_i)
45
+ unique_id.to_i >> bits.values.inject(&:+)
46
+ end
62
47
 
63
- define_method :"unique_#{pk}" do
64
- self.class.send(:"unique_#{pk}_from", send(pk), **send(:"#{pk}_group"))
48
+ define_method :"#{pk}_group_from" do |unique_id|
49
+ break nil if unique_id.nil?
50
+ raise TypeError, "unique_#{pk} must implement #to_i, #{unique_id.inspect} given" unless unique_id.respond_to?(:to_i)
51
+ Hash[group_totals.keys.reverse.map do |group_name|
52
+ g = unique_id & (totals[group_name] - 1)
53
+ unique_id >>= bits[group_name]
54
+ [group_name, g]
55
+ end.reverse]
56
+ end
65
57
  end
66
58
 
67
- define_singleton_method :"find_by_unique_#{pk}" do |unique_id|
68
- send(:"find_by_#{pk}", send(:"#{pk}_from", unique_id))
69
- end
59
+ generate_methods do
60
+ define_method :"#{pk}_group" do
61
+ group_from_block = group_block ? instance_eval(&group_block) : {}
62
+ raise TypeError, "#{pk} group block must return a Hash with any of the following keys: #{group_totals.keys}, #{group_from_block.inspect} given" unless group_from_block.is_a?(Hash)
63
+ raise ArgumentError, "unknown #{pk} group passed to block: #{group_from_block.keys - group_totals.keys}" if (group_from_block.keys - group_totals.keys).any?
64
+ Hash[(group_totals.keys - group_from_block.keys).map { |group_name| [group_name, send(group_name)] }].merge(group_from_block)
65
+ end
70
66
 
71
- define_singleton_method :"find_by_unique_#{pk}!" do |unique_id|
72
- send(:"find_by_#{pk}!", send(:"#{pk}_from", unique_id))
67
+ define_method :"unique_#{pk}" do
68
+ self.class.send(:"unique_#{pk}_from", send(pk), **send(:"#{pk}_group"))
69
+ end
73
70
  end
74
71
  end
75
72
  end
@@ -11,12 +11,6 @@ module BaseBill
11
11
  def primary_key
12
12
  :bill_id
13
13
  end
14
-
15
- def find_by_bill_id(bill_id)
16
- end
17
-
18
- def find_by_bill_id!(bill_id)
19
- end
20
14
  end
21
15
  end
22
16
 
@@ -29,17 +23,6 @@ class ShardedTablesBase < Struct.new(:bill_id, :client_id, :x)
29
23
  end
30
24
 
31
25
  describe UniqueBy::Generator do
32
- shared_context "finder methods" do
33
- specify "find_by_bill_id" do
34
- expect(klass).to receive(:find_by_bill_id).with(id)
35
- klass.find_by_unique_bill_id(unique_id)
36
- end
37
- specify "find_by_bill_id!" do
38
- expect(klass).to receive(:find_by_bill_id!).with(id)
39
- klass.find_by_unique_bill_id!(unique_id)
40
- end
41
- end
42
-
43
26
  context "shards" do
44
27
  let(:klass) do
45
28
  Class.new(Struct.new(:bill_id, :client_id)) do
@@ -67,8 +50,6 @@ describe UniqueBy::Generator do
67
50
  specify { expect(klass.bill_id_from(nil)).to be_nil }
68
51
  specify { expect(klass.bill_id_group_from(nil)).to be_nil }
69
52
  end
70
-
71
- include_context "finder methods"
72
53
  end
73
54
 
74
55
  describe "instance methods" do
@@ -91,8 +72,6 @@ describe UniqueBy::Generator do
91
72
  specify { expect(klass.unique_bill_id_from(431, client_id: 7)).to eq(unique_id) }
92
73
  specify { expect(klass.bill_id_from(unique_id)).to eq(431) }
93
74
  specify { expect(klass.bill_id_group_from(unique_id)).to eq(client_id: 7 % 16) }
94
-
95
- include_context "finder methods"
96
75
  end
97
76
 
98
77
  describe "instance methods" do
@@ -128,8 +107,6 @@ describe UniqueBy::Generator do
128
107
  specify { expect(medical_klass.unique_bill_id_from(839, type: 10)).to eq(unique_id) }
129
108
  specify { expect(medical_klass.bill_id_from(unique_id)).to eq(839) }
130
109
  specify { expect(medical_klass.bill_id_group_from(unique_id)).to eq(type: 10 % 2) }
131
-
132
- include_context "finder methods"
133
110
  end
134
111
 
135
112
  describe "instance methods" do
@@ -148,8 +125,6 @@ describe UniqueBy::Generator do
148
125
  specify { expect(utility_klass.unique_bill_id_from(839, type: 11)).to eq(unique_id) }
149
126
  specify { expect(utility_klass.bill_id_from(unique_id)).to eq(839) }
150
127
  specify { expect(utility_klass.bill_id_group_from(unique_id)).to eq(type: 11 % 2) }
151
-
152
- include_context "finder methods"
153
128
  end
154
129
 
155
130
  describe "instance methods" do
@@ -201,8 +176,6 @@ describe UniqueBy::Generator do
201
176
  specify { expect(medical_klass.unique_bill_id_from(9428, client_id: 5, x: 53, type: 10, y: 20)).to eq(unique_id) }
202
177
  specify { expect(medical_klass.bill_id_from(unique_id)).to eq(9428) }
203
178
  specify { expect(medical_klass.bill_id_group_from(unique_id)).to eq(tempered_group) }
204
-
205
- include_context "finder methods"
206
179
  end
207
180
 
208
181
  describe "instance methods" do
@@ -224,8 +197,6 @@ describe UniqueBy::Generator do
224
197
  specify { expect(utility_klass.unique_bill_id_from(9428, client_id: 8, x: 853, type: 11, y: 40)).to eq(unique_id) }
225
198
  specify { expect(utility_klass.bill_id_from(unique_id)).to eq(9428) }
226
199
  specify { expect(utility_klass.bill_id_group_from(unique_id)).to eq(tempered_group) }
227
-
228
- include_context "finder methods"
229
200
  end
230
201
 
231
202
  describe "instance methods" do
data/unique_by.gemspec CHANGED
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_runtime_dependency "generate_method", "~> 1.0"
22
+
21
23
  spec.add_development_dependency "bundler", "~> 1.6"
22
24
  spec.add_development_dependency "rspec", "~> 3.1"
23
25
  spec.add_development_dependency "rspec-its", "~> 1.0"
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unique_by
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oded Niv
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-25 00:00:00.000000000 Z
11
+ date: 2014-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: generate_method
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement