offline_lookup 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -0
- data/lib/offline_lookup/active_record.rb +20 -2
- data/lib/offline_lookup/base.rb +1 -46
- data/lib/offline_lookup/builder.rb +78 -17
- 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: 3f2b36619ce0489bb3be9209e0c6f375d6ad7b7f
|
4
|
+
data.tar.gz: 2a8b0b21903a8010032c6f99b9cfa5cfb7b5069d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1e8325950ade06e5daeeece7c496d717c26412c7be90119395442ef69f8cbd03f78b9dff2e9e1afb04dbd64710b5c7439215dce37da6683ce81a3f18eead93a
|
7
|
+
data.tar.gz: bf7fa6108c54b9dc3946d6ead0338e56f4a0996db3aabd14d83c75dc682694118c060a8bd66b5bce289bccc45e01c8e677b2a2891b31635395ba27d73ae10978
|
data/README.md
CHANGED
@@ -138,6 +138,21 @@ end
|
|
138
138
|
Admin.id_for_name("John Doe")
|
139
139
|
```
|
140
140
|
|
141
|
+
You can also define your own method of generaing the lookup name using the `:transform` options. The default is to ust the field, or delimiter-concatentaed fields. To specify a transofmation, provide a lambda whose arguments are the fields being used by OfflineLookup
|
142
|
+
|
143
|
+
```
|
144
|
+
class Admin < ActiveRecord::Base
|
145
|
+
use_offline_lookup :lastname, transform: ->(lastname){"lookup_#{lastname}"}
|
146
|
+
end
|
147
|
+
```
|
148
|
+
|
149
|
+
Or for multiple fields
|
150
|
+
```
|
151
|
+
class Admin < ActiveRecord::Base
|
152
|
+
use_offline_lookup :firstname, :lastname, transform: ->(first, last){"#{first.first}_#{last}"}
|
153
|
+
end
|
154
|
+
```
|
155
|
+
|
141
156
|
## Known Issues
|
142
157
|
|
143
158
|
If two entries in the table have the same value in the specified field, all but one will get overwritten.
|
@@ -3,7 +3,7 @@ module OfflineLookup
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
after_create :get_offline_lookup_values
|
6
|
+
after_create :get_offline_lookup_values, :add_offline_lookup
|
7
7
|
after_destroy :get_offline_lookup_values
|
8
8
|
end
|
9
9
|
|
@@ -11,6 +11,15 @@ module OfflineLookup
|
|
11
11
|
self.class.get_offline_lookup_values
|
12
12
|
end
|
13
13
|
|
14
|
+
def offline_lookup_value
|
15
|
+
self.class.offline_lookup_value(*offline_lookup_options[:fields].map{|f| self.attributes[f.to_s]})
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_offline_lookup
|
19
|
+
builder = OfflineLookup::Builder.new(self.class, self.offline_lookup_options)
|
20
|
+
builder.add_lookup(self.attributes[builder.key], offline_lookup_value)
|
21
|
+
end
|
22
|
+
|
14
23
|
module ClassMethods
|
15
24
|
def use_offline_lookup(*fields, key: "id", identity_methods: false, lookup_methods: false, compact: false, delimiter: " ", name: fields.join(delimiter), transform: nil)
|
16
25
|
class_attribute :offline_lookup_values, :offline_lookup_options
|
@@ -30,13 +39,22 @@ module OfflineLookup
|
|
30
39
|
include OfflineLookup::Base
|
31
40
|
end
|
32
41
|
|
42
|
+
def offline_lookup_value(*fields)
|
43
|
+
if offline_lookup_options[:transform].present?
|
44
|
+
offline_lookup_options[:transform].call(*fields.map(&:to_s))
|
45
|
+
else
|
46
|
+
fields.map(&:to_s).join(offline_lookup_options[:delimiter])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
33
50
|
def get_offline_lookup_values
|
34
51
|
self.offline_lookup_values = self.all.pluck(offline_lookup_options[:key], *offline_lookup_options[:fields]).map do |key, *fields|
|
35
52
|
fields.compact! if offline_lookup_options[:compact]
|
36
53
|
value = offline_lookup_options[:transform].present? ? offline_lookup_options[:transform].call(*fields.map(&:to_s)) : fields.map(&:to_s).join(offline_lookup_options[:delimiter])
|
37
|
-
[key, value]
|
54
|
+
[key, value.to_s]
|
38
55
|
end.to_h.freeze
|
39
56
|
end
|
57
|
+
|
40
58
|
end
|
41
59
|
end
|
42
60
|
end
|
data/lib/offline_lookup/base.rb
CHANGED
@@ -3,52 +3,7 @@ module OfflineLookup
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
|
7
|
-
|
8
|
-
### define value-named methods such as :two_hour_id and :two_hour?
|
9
|
-
|
10
|
-
self.offline_lookup_values.each do |key, value|
|
11
|
-
# class method: get key value (e.g. FooType.bar_id)
|
12
|
-
define_singleton_method(builder.key_method_name(value)) do
|
13
|
-
key
|
14
|
-
end
|
15
|
-
|
16
|
-
# instance method: true if instance is of named type (e.g. FooType.first.bar?)
|
17
|
-
if self.offline_lookup_options[:identity_methods]
|
18
|
-
define_method(builder.indentiy_method_name(value)) do
|
19
|
-
self.attributes[self.offline_lookup_options[:key]] == key
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# class method: get instance by named method (e.g. FooType.bar)
|
24
|
-
# not "Offline", but lookup by indexed key. Also, synactic sugar.
|
25
|
-
if self.offline_lookup_options[:lookup_methods]
|
26
|
-
define_singleton_method(builder.lookup_method_name(value)) do
|
27
|
-
key = self.offline_lookup_values.find{|k, v| v.to_s == value.to_s}.try(:first)
|
28
|
-
find(key)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# class method: get instance using more general `lookup` method
|
33
|
-
# Just as not "offline" as above, but less dangerous / more robust to any db value
|
34
|
-
define_singleton_method :lookup do |value|
|
35
|
-
key = self.offline_lookup_values.find{|k, v| v.to_s == value.to_s}.try(:first)
|
36
|
-
find_by(id: key)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
|
41
|
-
### define statically-named methods where you pass in the named value, e.g., id_for_name(:two_hour)
|
42
|
-
# e.g. FooType.name_for_id(1)
|
43
|
-
define_singleton_method(builder.field_for_key_method_name) do |key_value|
|
44
|
-
self.offline_lookup_values[key_value]
|
45
|
-
end
|
46
|
-
|
47
|
-
# e.g. FooType.id_for_name("Bar")
|
48
|
-
define_singleton_method(builder.key_for_field_method_name) do |field_value|
|
49
|
-
self.offline_lookup_values.find{|k, v| v.to_s == field_value.to_s}.try(:first)
|
50
|
-
end
|
51
|
-
|
6
|
+
OfflineLookup::Builder.new(self, self.offline_lookup_options).build
|
52
7
|
end
|
53
8
|
end
|
54
9
|
end
|
@@ -1,15 +1,46 @@
|
|
1
1
|
module OfflineLookup
|
2
2
|
class Builder
|
3
|
-
|
3
|
+
attr_reader :fields, :key, :name
|
4
|
+
def initialize(model, options)
|
5
|
+
@model = model
|
4
6
|
@fields = options[:fields]
|
5
7
|
@key = options[:key]
|
6
8
|
@name = options[:name]
|
9
|
+
@build_identity_methods = options[:identity_methods]
|
10
|
+
@build_lookup_methods = options[:lookup_methods]
|
11
|
+
@modyule = get_module || create_module
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_module
|
15
|
+
@model.const_defined?("OfflineLookupMethods") && @model::OfflineLookupMethods
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_module
|
19
|
+
@modyule = Module.new
|
20
|
+
@modyule.extend ActiveSupport::Concern
|
21
|
+
@modyule.const_set("ClassMethods", Module.new)
|
22
|
+
@model.const_set("OfflineLookupMethods", @modyule)
|
23
|
+
end
|
24
|
+
|
25
|
+
def build
|
26
|
+
@model.offline_lookup_values.each do |key, value|
|
27
|
+
add_lookup(key, value)
|
28
|
+
end
|
29
|
+
add_name_for_key_method
|
30
|
+
add_key_for_name_method
|
31
|
+
add_static_lookup_method
|
32
|
+
@model.include @modyule
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_lookup(key, value)
|
36
|
+
add_key_lookup_method(key, value)
|
37
|
+
add_identity_method(key, value) if @build_identity_methods
|
38
|
+
add_lookup_method(key, value) if @build_lookup_methods
|
7
39
|
end
|
8
40
|
|
9
41
|
def sanitize(string)
|
10
|
-
#:methodize went away. Where did it go?
|
11
42
|
#1. Replace illegal chars and _ boundaries with " " boundary
|
12
|
-
string = string.gsub(/[^a-zA-Z\d]+/," ").strip
|
43
|
+
string = string.to_s.gsub(/[^a-zA-Z\d]+/," ").strip
|
13
44
|
#2. Insert " " boundary at snake-case boundaries
|
14
45
|
string.gsub!(/([a-z])([A-Z])/){|s| "#{$1} #{$2}"}
|
15
46
|
#3. underscore
|
@@ -20,28 +51,58 @@ module OfflineLookup
|
|
20
51
|
return string
|
21
52
|
end
|
22
53
|
|
23
|
-
# e.g
|
24
|
-
def
|
25
|
-
|
54
|
+
# Get key value (e.g. FooType.bar_id)
|
55
|
+
def add_key_lookup_method(key, value)
|
56
|
+
@modyule::ClassMethods.instance_exec(self, key, value) do |builder, key, value|
|
57
|
+
define_method builder.sanitize("#{value}_#{builder.key}") do
|
58
|
+
key
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Return true iff instance is of named type (e.g. FooType.first.bar?)
|
64
|
+
def add_identity_method(key, value)
|
65
|
+
@modyule.instance_exec(self, key, value) do |builder, key, value|
|
66
|
+
define_method builder.sanitize(value) + "?" do
|
67
|
+
self.attributes[builder.key] == key
|
68
|
+
end
|
69
|
+
end
|
26
70
|
end
|
27
71
|
|
28
|
-
|
29
|
-
|
72
|
+
# Get instance by named method (e.g. FooType.bar) (Not offline, but syntactic sugar)
|
73
|
+
def add_lookup_method(key, value)
|
74
|
+
@modyule::ClassMethods.instance_exec(self, key, value) do |builder, key, value|
|
75
|
+
define_method builder.sanitize(value) do
|
76
|
+
find_by(builder.key => self.offline_lookup_values.key(value.to_s))
|
77
|
+
end
|
78
|
+
end
|
30
79
|
end
|
31
80
|
|
32
|
-
# e.g
|
33
|
-
def
|
34
|
-
|
81
|
+
# e.g. FooType.name_for_id(1)
|
82
|
+
def add_name_for_key_method
|
83
|
+
@modyule::ClassMethods.instance_exec(self) do |builder|
|
84
|
+
define_method builder.sanitize("#{builder.name}_for_#{builder.key}") do |key|
|
85
|
+
self.offline_lookup_values[key]
|
86
|
+
end
|
87
|
+
end
|
35
88
|
end
|
36
89
|
|
37
|
-
# e.g.
|
38
|
-
def
|
39
|
-
|
90
|
+
# e.g. FooType.id_for_name("Bar")
|
91
|
+
def add_key_for_name_method
|
92
|
+
@modyule::ClassMethods.instance_exec(self) do |builder|
|
93
|
+
define_method builder.sanitize("#{builder.key}_for_#{builder.name}") do |value|
|
94
|
+
self.offline_lookup_values.key(value.to_s)
|
95
|
+
end
|
96
|
+
end
|
40
97
|
end
|
41
98
|
|
42
|
-
# e.g.
|
43
|
-
def
|
44
|
-
|
99
|
+
# e.g. FooType.lookup("Bar")
|
100
|
+
def add_static_lookup_method
|
101
|
+
@modyule::ClassMethods.instance_exec(self) do |builder|
|
102
|
+
define_method "lookup" do |value|
|
103
|
+
find_by(builder.key => self.offline_lookup_values.key(value.to_s))
|
104
|
+
end
|
105
|
+
end
|
45
106
|
end
|
46
107
|
|
47
108
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: offline_lookup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Schwartz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Offline indexing of small tables syntactic sugar & less db touching
|
14
14
|
email: ozydingo@gmail.com
|