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 +4 -4
- data/README.md +35 -9
- data/lib/unique_by/version.rb +1 -1
- data/lib/unique_by.rb +40 -43
- data/spec/unique_by_spec.rb +0 -29
- data/unique_by.gemspec +2 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5403c00bf28bbe7858fa14d407bdbda99527de7e
|
4
|
+
data.tar.gz: e9e0dcd9a442febb74ffd046edda31edfc9f4f9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 =
|
159
|
+
bill = MedicalBill.find(3528918) # from a DB shard for client_id = 78
|
134
160
|
bill.unique_id
|
135
|
-
=> "
|
136
|
-
|
137
|
-
=>
|
161
|
+
=> "ywr3b2e"
|
162
|
+
bill.unique_id_without_rebase
|
163
|
+
=> 1806806094
|
138
164
|
```
|
139
165
|
|
140
166
|
## Contributing
|
data/lib/unique_by/version.rb
CHANGED
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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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
|
-
|
64
|
-
|
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
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
72
|
-
|
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
|
data/spec/unique_by_spec.rb
CHANGED
@@ -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.
|
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-
|
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
|