unique_by 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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