acts_as_splittable 0.0.6 → 0.0.7
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 +5 -4
- data/lib/acts_as_splittable.rb +28 -16
- data/lib/acts_as_splittable/splittable.rb +20 -14
- data/lib/acts_as_splittable/splitter.rb +19 -6
- data/lib/acts_as_splittable/version.rb +1 -1
- data/spec/models.rb +11 -4
- data/spec/models/splittable_spec.rb +49 -0
- data/spec/schema.rb +1 -0
- 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: 637013ac8fc1b1ed1e0bb79b28fd09caa2ec9172
|
4
|
+
data.tar.gz: 708003b189efb2ef05eba73a960a35cd5190c5ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d4999d86e3455f1ee8f1a711ba2165035ca7cf2bb6b8123a8a1b84b523235bc3561e9862a6ee870ccd28daedf3a277a0e22c128199e16016f74e5a1389635ba
|
7
|
+
data.tar.gz: 580d2eda99d8b58e629062f99deb5a36fed68a83575ce9aa3e79d57e8bfe7d25287ce01723cfa3d1568d22206c4e69c4cfeaef41c20f5d631e99c184a85d3adf
|
data/README.md
CHANGED
@@ -34,9 +34,9 @@ class Splittable < ActiveRecord::Base
|
|
34
34
|
|
35
35
|
acts_as_splittable
|
36
36
|
|
37
|
-
splittable :email, split: ['@', 2],
|
37
|
+
splittable :email, split: ['@', 2], attributes: [:email_local, :email_domain], on_join: Proc.new{|values| values.join('@') }
|
38
38
|
splittable :postal_code, pattern: /\A(?<postal_code1>[0-9]{3})(?<postal_code2>[0-9]{4})\Z/
|
39
|
-
splittable :phone_number,
|
39
|
+
splittable :phone_number, attributes: [:phone_number1, :phone_number2, :phone_number3], on_split: :split_phone_number, on_join: :join_phone_number
|
40
40
|
|
41
41
|
validates :email_local, format: { with: /\A[a-zA-Z0-9_.-]+\Z/ }
|
42
42
|
validates :email_domain, format: { with: /\A(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,4}\Z/ }
|
@@ -144,7 +144,8 @@ p splittable.email_domain #=> "example.com"
|
|
144
144
|
```ruby
|
145
145
|
class Splittable < ActiveRecord::Base
|
146
146
|
|
147
|
-
|
147
|
+
acts_as_hasty_splittable
|
148
|
+
# same as `acts_as_splittable split_on_change: true, join_on_change: true, callbacks: false`
|
148
149
|
|
149
150
|
# ...
|
150
151
|
end
|
@@ -178,7 +179,7 @@ class Splittable < ActiveRecord::Base
|
|
178
179
|
|
179
180
|
acts_as_splittable split_on_change: true, join_on_change: true
|
180
181
|
|
181
|
-
splittable :email, delimiter: '@',
|
182
|
+
splittable :email, delimiter: '@', attributes: [:email_local, :email_domain]
|
182
183
|
# :delimiter will be expanded to:
|
183
184
|
# {
|
184
185
|
# split: ['@'],
|
data/lib/acts_as_splittable.rb
CHANGED
@@ -30,6 +30,10 @@ module ActsAsSplittable
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
def acts_as_hasty_splittable(options = {})
|
34
|
+
acts_as_splittable options.reverse_merge(join_on_change: true, split_on_change: true, callbacks: false)
|
35
|
+
end
|
36
|
+
|
33
37
|
module ClassMethods
|
34
38
|
attr_writer :splittable_options
|
35
39
|
|
@@ -54,10 +58,10 @@ module ActsAsSplittable
|
|
54
58
|
splitter = Splitter.new(options)
|
55
59
|
splittable_config.splitters << splitter
|
56
60
|
|
57
|
-
splitter.
|
58
|
-
define_splittable_getter(
|
59
|
-
define_splittable_setter(
|
60
|
-
define_splittable_predicator(
|
61
|
+
splitter.attributes.each do |attribute|
|
62
|
+
define_splittable_getter(attribute)
|
63
|
+
define_splittable_setter(attribute, splitter)
|
64
|
+
define_splittable_predicator(attribute) if splittable_options[:predicates]
|
61
65
|
end
|
62
66
|
|
63
67
|
if splittable_options[:split_on_change]
|
@@ -69,29 +73,37 @@ module ActsAsSplittable
|
|
69
73
|
super
|
70
74
|
|
71
75
|
child.splittable_options = splittable_options.dup
|
76
|
+
|
77
|
+
if child.splittable_options[:split_on_change]
|
78
|
+
child.splittable_module = splittable_module.dup
|
79
|
+
child.send(:include, child.splittable_module)
|
80
|
+
end
|
81
|
+
|
72
82
|
child.splittable_config.inherit! splittable_config
|
73
83
|
end
|
74
84
|
|
75
85
|
protected
|
76
86
|
|
87
|
+
attr_writer :splittable_module
|
88
|
+
|
77
89
|
def splittable_module
|
78
90
|
@splittable_module ||= Module.new
|
79
91
|
end
|
80
|
-
|
92
|
+
|
81
93
|
private
|
82
94
|
|
83
|
-
def define_splittable_getter(
|
84
|
-
define_method
|
85
|
-
|
95
|
+
def define_splittable_getter(attribute)
|
96
|
+
define_method attribute do
|
97
|
+
splittable_attributes[attribute]
|
86
98
|
end
|
87
99
|
end
|
88
100
|
|
89
|
-
def define_splittable_setter(
|
90
|
-
define_method :"#{
|
91
|
-
|
101
|
+
def define_splittable_setter(attribute, splitter)
|
102
|
+
define_method :"#{attribute}=" do |value|
|
103
|
+
splittable_attributes[attribute] = value
|
92
104
|
|
93
|
-
unless
|
94
|
-
|
105
|
+
unless splittable_changed_attribute? attribute
|
106
|
+
splittable_changed_attributes << attribute
|
95
107
|
end
|
96
108
|
|
97
109
|
self.class.with_splittable_options split_on_change: false do |options|
|
@@ -102,9 +114,9 @@ module ActsAsSplittable
|
|
102
114
|
end
|
103
115
|
end
|
104
116
|
|
105
|
-
def define_splittable_predicator(
|
106
|
-
define_method :"#{
|
107
|
-
|
117
|
+
def define_splittable_predicator(attribute)
|
118
|
+
define_method :"#{attribute}_changed?" do
|
119
|
+
splittable_changed_attribute? attribute
|
108
120
|
end
|
109
121
|
end
|
110
122
|
|
@@ -1,51 +1,57 @@
|
|
1
1
|
module ActsAsSplittable
|
2
2
|
module Splittable
|
3
3
|
|
4
|
-
def
|
5
|
-
@
|
4
|
+
def splittable_attributes
|
5
|
+
@splittable_attributes ||= {}
|
6
6
|
end
|
7
7
|
|
8
|
+
alias_method :splittable_partials, :splittable_attributes
|
9
|
+
|
8
10
|
def split_column_values!(columns = nil)
|
9
11
|
splittable_aggregate_columns(columns) do |column, splitter|
|
10
12
|
value = __send__(column) or next
|
11
13
|
|
12
14
|
values = splitter.split(value, self)
|
13
|
-
splitter.
|
15
|
+
splitter.attributes.zip(values).each do |key, value|
|
14
16
|
__send__ :"#{key}=", value
|
15
17
|
end
|
16
|
-
|
18
|
+
reset_splittable_changed_attributes splitter.attributes
|
17
19
|
end
|
18
20
|
self
|
19
21
|
end
|
20
22
|
|
21
23
|
def join_column_values!(columns = nil)
|
22
24
|
splittable_aggregate_columns(columns) do |column, splitter|
|
23
|
-
values = splitter.
|
25
|
+
values = splitter.attributes.map {|partial| __send__(partial) }
|
24
26
|
next if values.include?(nil)
|
25
27
|
|
26
28
|
__send__ :"#{column}=", splitter.restore(values, self)
|
27
|
-
|
29
|
+
reset_splittable_changed_attributes splitter.attributes
|
28
30
|
end
|
29
31
|
self
|
30
32
|
end
|
31
33
|
|
32
34
|
protected
|
33
35
|
|
34
|
-
attr_writer :
|
36
|
+
attr_writer :splittable_changed_attributes
|
35
37
|
|
36
|
-
def
|
37
|
-
@
|
38
|
+
def splittable_changed_attributes
|
39
|
+
@splittable_changed_attributes ||= []
|
38
40
|
end
|
39
41
|
|
40
|
-
def
|
41
|
-
|
42
|
+
def splittable_changed_attribute?(attribute)
|
43
|
+
splittable_changed_attributes.include? attribute
|
42
44
|
end
|
43
45
|
|
44
|
-
def
|
45
|
-
self.
|
46
|
-
self.
|
46
|
+
def reset_splittable_changed_attributes(attributes)
|
47
|
+
self.splittable_changed_attributes.uniq!
|
48
|
+
self.splittable_changed_attributes -= attributes
|
47
49
|
end
|
48
50
|
|
51
|
+
alias_method :splittable_changed_partials, :splittable_changed_attributes
|
52
|
+
alias_method :splittable_changed_partial?, :splittable_changed_attribute?
|
53
|
+
alias_method :reset_splittable_changed_partials, :reset_splittable_changed_attributes
|
54
|
+
|
49
55
|
private
|
50
56
|
def splittable_aggregate_columns(columns = nil)
|
51
57
|
config = self.class.splittable_config
|
@@ -1,13 +1,14 @@
|
|
1
1
|
module ActsAsSplittable
|
2
|
-
class Splitter < Struct.new(:name, :for_split, :pattern, :
|
2
|
+
class Splitter < Struct.new(:name, :for_split, :pattern, :attributes, :on_split, :on_join, :type)
|
3
3
|
DEFAULTS = {
|
4
4
|
on_join: Proc.new {|values| values.join }
|
5
5
|
}.freeze
|
6
6
|
|
7
7
|
ALIASES = {
|
8
|
-
split:
|
9
|
-
column:
|
10
|
-
regex:
|
8
|
+
split: :for_split,
|
9
|
+
column: :name,
|
10
|
+
regex: :pattern,
|
11
|
+
partials: :attributes,
|
11
12
|
}.freeze
|
12
13
|
|
13
14
|
def initialize(options = {})
|
@@ -30,11 +31,11 @@ module ActsAsSplittable
|
|
30
31
|
self.on_join = Proc.new {|values| values.join(delimiter)}
|
31
32
|
end
|
32
33
|
|
33
|
-
self.
|
34
|
+
self.attributes ||= pattern_members
|
34
35
|
end
|
35
36
|
|
36
37
|
def split(value, delegate = nil)
|
37
|
-
case
|
38
|
+
cast case
|
38
39
|
when on_split
|
39
40
|
delegation(delegate || self, on_split, value)
|
40
41
|
when for_split
|
@@ -62,5 +63,17 @@ module ActsAsSplittable
|
|
62
63
|
def pattern_members
|
63
64
|
pattern.names.map(&:to_sym)
|
64
65
|
end
|
66
|
+
|
67
|
+
def cast(values)
|
68
|
+
case type
|
69
|
+
when Proc, Symbol
|
70
|
+
values.map(&type)
|
71
|
+
when Class
|
72
|
+
name = type.name.to_sym
|
73
|
+
|
74
|
+
values.map{|value| Object.__send__(name, value) } if
|
75
|
+
Object.private_method_defined?(name)
|
76
|
+
end || values
|
77
|
+
end
|
65
78
|
end
|
66
79
|
end
|
data/spec/models.rb
CHANGED
@@ -5,9 +5,9 @@ class Splittable < ActiveRecord::Base
|
|
5
5
|
|
6
6
|
acts_as_splittable predicates: true
|
7
7
|
|
8
|
-
splittable :email, split: ['@', 2],
|
8
|
+
splittable :email, split: ['@', 2], attributes: [:email_local, :email_domain], on_join: EMAIL_JOIN_PROCESS
|
9
9
|
splittable :postal_code, pattern: /\A(?<postal_code1>[0-9]{3})(?<postal_code2>[0-9]{4})\Z/
|
10
|
-
splittable :phone_number,
|
10
|
+
splittable :phone_number, attributes: [:phone_number1, :phone_number2, :phone_number3], on_split: :split_phone_number, on_join: :join_phone_number
|
11
11
|
|
12
12
|
protected
|
13
13
|
|
@@ -48,7 +48,8 @@ end
|
|
48
48
|
class SplittableSplitOrJoinOnChange < ActiveRecord::Base
|
49
49
|
self.table_name = 'splittables'
|
50
50
|
|
51
|
-
|
51
|
+
acts_as_hasty_splittable
|
52
|
+
# same as `acts_as_splittable join_on_change: true, split_on_change: true, callbacks: false`
|
52
53
|
|
53
54
|
splittable :email, pattern: EMAIL_SPLIT_PATTERN, on_join: EMAIL_JOIN_PROCESS
|
54
55
|
|
@@ -72,5 +73,11 @@ class SplittableUseDelimiter < ActiveRecord::Base
|
|
72
73
|
|
73
74
|
acts_as_splittable join_on_change: true, split_on_change: true, callbacks: false
|
74
75
|
|
75
|
-
splittable :email, delimiter: '@',
|
76
|
+
splittable :email, delimiter: '@', attributes: [:email_local, :email_domain]
|
77
|
+
end
|
78
|
+
|
79
|
+
class SplittableUseTypeCasting < ActiveRecord::Base
|
80
|
+
self.table_name = 'splittables'
|
81
|
+
|
82
|
+
acts_as_hasty_splittable
|
76
83
|
end
|
@@ -279,3 +279,52 @@ describe SplittableUseDelimiter do
|
|
279
279
|
end
|
280
280
|
|
281
281
|
end
|
282
|
+
|
283
|
+
describe SplittableUseTypeCasting do
|
284
|
+
|
285
|
+
shared_examples_for 'splittable typecasting' do
|
286
|
+
|
287
|
+
it 'should typecast' do
|
288
|
+
splittable.lat.should == 35.629902
|
289
|
+
splittable.lng.should == 139.793934
|
290
|
+
end
|
291
|
+
|
292
|
+
it 'should restore' do
|
293
|
+
splittable.lat = 51.476877
|
294
|
+
splittable.lng = -0.00033
|
295
|
+
splittable.latlng.should == '51.476877,-0.00033'
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|
299
|
+
|
300
|
+
context 'with method' do
|
301
|
+
let (:splittable) do
|
302
|
+
Class.new(SplittableUseTypeCasting) {
|
303
|
+
splittable :latlng, delimiter: ',', attributes: [:lat, :lng], type: Float
|
304
|
+
}.new(latlng: '35.629902,139.793934')
|
305
|
+
end
|
306
|
+
|
307
|
+
it_behaves_like 'splittable typecasting'
|
308
|
+
end
|
309
|
+
|
310
|
+
context 'with Proc' do
|
311
|
+
let (:splittable) do
|
312
|
+
Class.new(SplittableUseTypeCasting) {
|
313
|
+
splittable :latlng, delimiter: ',', attributes: [:lat, :lng], type: Proc.new{|value| value.to_f }
|
314
|
+
}.new(latlng: '35.629902,139.793934')
|
315
|
+
end
|
316
|
+
|
317
|
+
it_behaves_like 'splittable typecasting'
|
318
|
+
end
|
319
|
+
|
320
|
+
context 'with Symbol' do
|
321
|
+
let (:splittable) do
|
322
|
+
Class.new(SplittableUseTypeCasting) {
|
323
|
+
splittable :latlng, delimiter: ',', attributes: [:lat, :lng], type: :to_f
|
324
|
+
}.new(latlng: '35.629902,139.793934')
|
325
|
+
end
|
326
|
+
|
327
|
+
it_behaves_like 'splittable typecasting'
|
328
|
+
end
|
329
|
+
|
330
|
+
end
|
data/spec/schema.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_splittable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- tatat
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-06-
|
13
|
+
date: 2013-06-26 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|