acts_as_splittable 0.0.4 → 0.0.5

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: 9c322425fe4d630018ee8191f6faa6dac4e28429
4
- data.tar.gz: e4991fe6c463cdac97e36df4121efcd316f43d55
3
+ metadata.gz: 0398f1488b36c65e7f0573f2b0c1e8b103e2c0cd
4
+ data.tar.gz: ebc482f510f36b2d4e96b52bb2a658afdab6f1dc
5
5
  SHA512:
6
- metadata.gz: e7143c847c534b3ffe2146ab7b148a8e8ec154a0e906a4130c4a7d1fb3faec7da57236b7aea94ff882c0579192b082f8a57ad33981bc4f94b8210f57d51251e6
7
- data.tar.gz: 5e844b023d12fd13779bd052d10507c532c50c98c71dfa577d9ae04b7b778dce242f1173297e718b2d020d4b4a7413de1ea63078e2029772c3112682ef17108c
6
+ metadata.gz: e2a3c47fe22bf41f4d68cc895ac283f0ea6b1b0ed8aac4e642069cf5ccaec769ff497d3e8eabb2f61309e4c057ae07daaade3a88e5ba3ae5416e0dd7e79f04ab
7
+ data.tar.gz: dfd523946987d69389c3a3580b176aa28b3bc294b548ecc0c5f198e5a684c3777c3f658c28f19f4d59666c2ccae9b9ab81c3ec87ab58f895a11f69f9190cf6d6
data/README.md CHANGED
@@ -139,6 +139,38 @@ p splittable.email_local #=> "splittable"
139
139
  p splittable.email_domain #=> "example.com"
140
140
  ```
141
141
 
142
+ ### Automatically (without callbacks)
143
+
144
+ ```ruby
145
+ class Splittable < ActiveRecord::Base
146
+
147
+ acts_as_splittable split_on_change: true, join_on_change: true, callbacks: false
148
+
149
+ # ...
150
+ end
151
+ ```
152
+
153
+ then
154
+
155
+ ```ruby
156
+ splittable = Splittable.new(
157
+ email_local: 'splittable',
158
+ email_domain: 'example.com',
159
+ )
160
+
161
+ p splittable.email #=> "splittable@example.com"
162
+ p splittable.valid? #=> true
163
+ ```
164
+
165
+ and
166
+
167
+ ```ruby
168
+ splittable = Splittable.find(splittable_id)
169
+
170
+ p splittable.email_local #=> "splittable"
171
+ p splittable.email_domain #=> "example.com"
172
+ ```
173
+
142
174
  Contributing
143
175
  --------------------
144
176
 
@@ -0,0 +1,84 @@
1
+ module ActsAsSplittable
2
+
3
+ module Splittable
4
+
5
+ def split_column_values!(column = nil)
6
+ if column.nil?
7
+ self.class.splittable_columns.each_key{|key| send __method__, key }
8
+ else
9
+ column = column.to_sym
10
+ split, pattern, partials, on_split, on_join = self.class.splittable_columns[column]
11
+ value = send(column)
12
+
13
+ unless value.nil?
14
+ values = if on_split
15
+ splittable_run_callback(on_split, value)
16
+ elsif value
17
+ if split
18
+ value.to_s.split *(split.is_a?(Array) ? split : [split])
19
+ elsif matches = value.to_s.match(pattern)
20
+ matches[1..(matches.length - 1)]
21
+ end
22
+ end || []
23
+
24
+ partials.each_with_index do |partial, index|
25
+ send :"#{partial}=", values[index]
26
+ end
27
+
28
+ reset_splittable_changed_partials partials
29
+ end
30
+ end
31
+
32
+ self
33
+ end
34
+
35
+ def join_column_values!(column = nil)
36
+ if column.nil?
37
+ self.class.splittable_columns.each_key{|key| send __method__, key }
38
+ else
39
+ split, pattern, partials, on_split, on_join = self.class.splittable_columns[column.to_sym]
40
+ values = partials.map{|partial| send(partial) }
41
+
42
+ unless values.any?(&:nil?)
43
+ send :"#{column}=", splittable_run_callback(on_join, values)
44
+ reset_splittable_changed_partials partials
45
+ end
46
+ end
47
+
48
+ self
49
+ end
50
+
51
+ def splittable_partials
52
+ @splittable_partials ||= {}
53
+ end
54
+
55
+ protected
56
+
57
+ attr_writer :splittable_changed_partials
58
+
59
+ def splittable_changed_partials
60
+ @splittable_changed_partials ||= []
61
+ end
62
+
63
+ def splittable_changed_partial?(partial)
64
+ splittable_changed_partials.include? partial
65
+ end
66
+
67
+ def reset_splittable_changed_partials(partials)
68
+ self.splittable_changed_partials.uniq!
69
+ self.splittable_changed_partials -= partials
70
+ end
71
+
72
+ private
73
+
74
+ def splittable_run_callback(callback, *args)
75
+ if callback.is_a?(Proc)
76
+ instance_exec(*args, &callback)
77
+ else
78
+ send(callback, *args)
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ end
@@ -1,3 +1,3 @@
1
1
  module ActsAsSplittable
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -1,16 +1,28 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__)
2
+
1
3
  require 'active_record'
4
+ require 'acts_as_splittable/splittable'
2
5
 
3
6
  module ActsAsSplittable
4
7
 
5
8
  def acts_as_splittable(options = {})
6
- options.reverse_merge!(
7
- callbacks: true,
9
+ options = options.reverse_merge!(
10
+ callbacks: true,
11
+ predicates: false,
12
+ join_on_change: false,
13
+ split_on_change: false,
8
14
  )
9
15
 
10
16
  extend ClassMethods
11
- include InstanceMethods
17
+ include Splittable
18
+
19
+ self.splittable_options = options
12
20
 
13
- if options[:callbacks]
21
+ if splittable_options[:split_on_change]
22
+ include splittable_module
23
+ end
24
+
25
+ if splittable_options[:callbacks]
14
26
  after_initialize { new_record? or split_column_values! }
15
27
  before_save { join_column_values! }
16
28
  end
@@ -19,6 +31,19 @@ module ActsAsSplittable
19
31
  module ClassMethods
20
32
  SPLITTABLE_DEFAULT_JOIN_PROCESS = Proc.new{|values| values.join }
21
33
 
34
+ attr_writer :splittable_options
35
+
36
+ def splittable_options(other_options = {})
37
+ @splittable_options ||= {}
38
+ end
39
+
40
+ def with_splittable_options(other_options = {})
41
+ original_options = splittable_options
42
+ self.splittable_options = splittable_options.merge(other_options)
43
+ Proc.new.(splittable_options)
44
+ self.splittable_options = original_options
45
+ end
46
+
22
47
  def splittable_columns
23
48
  @splittable_columns ||= {}
24
49
  end
@@ -35,75 +60,51 @@ module ActsAsSplittable
35
60
 
36
61
  define_method :"#{partial}=" do |value|
37
62
  splittable_partials[partial] = value
38
- end
39
- end
40
- end
41
-
42
- def inherited(child)
43
- super
44
- child.splittable_columns.merge! splittable_columns.dup
45
- end
46
- end
63
+ splittable_changed_partials << partial unless splittable_changed_partial? partial
47
64
 
48
- module InstanceMethods
49
- def split_column_values!(column = nil)
50
- if column.nil?
51
- self.class.splittable_columns.each_key{|key| send __method__, key }
52
- else
53
- column = column.to_sym
54
- split, pattern, partials, on_split, on_join = self.class.splittable_columns[column]
55
- value = send(column)
56
-
57
- unless value.nil?
58
- values = if on_split
59
- run_callback(on_split, value)
60
- elsif value
61
- if split
62
- value.to_s.split *(split.is_a?(Array) ? split : [split])
63
- else
64
- matches = value.to_s.match(pattern)
65
- matches[1..(matches.length - 1)]
66
- end
67
- end || []
68
-
69
- partials.each_with_index do |partial, index|
70
- send :"#{partial}=", values[index]
65
+ self.class.with_splittable_options split_on_change: false do |options|
66
+ join_column_values! column if options[:join_on_change]
71
67
  end
72
68
  end
73
- end
74
-
75
- self
76
- end
77
69
 
78
- def join_column_values!(column = nil)
79
- if column.nil?
80
- self.class.splittable_columns.each_key{|key| send __method__, key }
81
- else
82
- split, pattern, partials, on_split, on_join = self.class.splittable_columns[column.to_sym]
83
- partials = partials.map{|partial| send(partial) }
84
-
85
- unless partials.any?(&:nil?)
86
- send :"#{column}=", run_callback(on_join, partials)
70
+ if splittable_options[:predicates]
71
+ define_method :"#{partial}_changed?" do
72
+ splittable_changed_partial? partial
73
+ end
87
74
  end
88
75
  end
89
76
 
90
- self
77
+ if splittable_options[:split_on_change]
78
+ splittable_module.module_eval <<-"EOS"
79
+ def #{column}=(value)
80
+ if defined?(super)
81
+ super
82
+ elsif respond_to?(:write_attribute, true)
83
+ write_attribute :#{column}, value
84
+ end
85
+
86
+ self.class.with_splittable_options join_on_change: false do
87
+ split_column_values! :#{column}
88
+ end
89
+ end
90
+ EOS
91
+ end
91
92
  end
92
93
 
93
- def splittable_partials
94
- @splittable_partials ||= {}
94
+ def inherited(child)
95
+ super
96
+
97
+ child.splittable_options = splittable_options.dup
98
+ child.splittable_columns.merge! splittable_columns.dup
95
99
  end
96
100
 
97
- private
101
+ protected
98
102
 
99
- def run_callback(callback, *args)
100
- if callback.is_a?(Proc)
101
- instance_exec(*args, &callback)
102
- else
103
- send(callback, *args)
104
- end
103
+ def splittable_module
104
+ @splittable_module ||= Module.new
105
105
  end
106
106
  end
107
+
107
108
  end
108
109
 
109
110
  ActiveRecord::Base.extend ActsAsSplittable
@@ -47,7 +47,7 @@ require 'spec_helper'
47
47
 
48
48
  it 'should split columns after initialize' do
49
49
  @splittables.each do |record|
50
- splittable = Splittable.find(record.id)
50
+ splittable = klass.find(record.id)
51
51
 
52
52
  splittable.email_local.should == 'splittable'
53
53
  splittable.email_domain.should == 'example.com'
@@ -59,6 +59,39 @@ require 'spec_helper'
59
59
  end
60
60
  end
61
61
 
62
+ describe '#*_changed?' do
63
+ before do
64
+ @splittable = klass.new
65
+ end
66
+
67
+ it 'should return true when value is changed until #split_column_values! or #join_column_values! is called' do
68
+ @splittable.email_local_changed?.should_not be_true
69
+ @splittable.email_domain_changed?.should_not be_true
70
+
71
+ @splittable.email_local = 'splittable'
72
+ @splittable.email_local_changed?.should be_true
73
+
74
+ @splittable.email_domain = 'example.com'
75
+ @splittable.email_domain_changed?.should be_true
76
+
77
+ @splittable.join_column_values!
78
+
79
+ @splittable.email_local_changed?.should_not be_true
80
+ @splittable.email_domain_changed?.should_not be_true
81
+
82
+ @splittable.email_local = nil
83
+ @splittable.email_local_changed?.should be_true
84
+
85
+ @splittable.email_domain = nil
86
+ @splittable.email_domain_changed?.should be_true
87
+
88
+ @splittable.split_column_values!
89
+
90
+ @splittable.email_local_changed?.should_not be_true
91
+ @splittable.email_domain_changed?.should_not be_true
92
+ end
93
+ end
94
+
62
95
  context 'when nil includes in partials or value of column is nil' do
63
96
  before :each do
64
97
  @splittable1 = klass.new(name: "#{klass.name} 1")
@@ -133,3 +166,80 @@ describe Splittable do
133
166
  end
134
167
  end
135
168
  end
169
+
170
+ describe SplittableSplitOrJoinOnChange do
171
+
172
+ it 'should join partials when one of partials is set and all of them are not nil' do
173
+ splittable = SplittableSplitOrJoinOnChange.new
174
+
175
+ splittable.email_local = 'splittable'
176
+ splittable.email_domain = 'example.com'
177
+
178
+ splittable.email.should == 'splittable@example.com'
179
+
180
+ splittable.email = nil
181
+
182
+ splittable.phone_number1 = '012'
183
+ splittable.phone_number.should be_nil
184
+
185
+ splittable.phone_number2 = '3456'
186
+ splittable.phone_number.should be_nil
187
+
188
+ splittable.phone_number3 = '7890'
189
+ splittable.phone_number.should == '012-3456-7890'
190
+
191
+ splittable.phone_number3 = '0000'
192
+ splittable.phone_number.should == '012-3456-0000'
193
+
194
+ splittable.email.should be_nil
195
+ end
196
+
197
+ it 'should split value when value is set' do
198
+ splittable1 = SplittableSplitOrJoinOnChange.new(
199
+ email: 'splittable@example.com',
200
+ phone_number: '012-3456-7890',
201
+ )
202
+
203
+ splittable2 = SplittableSplitOrJoinOnChange.new
204
+ splittable2.email = 'splittable@example.com'
205
+ splittable2.phone_number = '012-3456-7890'
206
+
207
+ [splittable1, splittable2].each do |splittable|
208
+ splittable.email_local.should == 'splittable'
209
+ splittable.email_domain.should == 'example.com'
210
+ splittable.phone_number1.should == '012'
211
+ splittable.phone_number2.should == '3456'
212
+ splittable.phone_number3.should == '7890'
213
+ end
214
+
215
+ splittable1.phone_number = '000-0000-0000'
216
+
217
+ splittable1.phone_number1.should == '000'
218
+ splittable1.phone_number2.should == '0000'
219
+ splittable1.phone_number3.should == '0000'
220
+ end
221
+
222
+ end
223
+
224
+ describe SplittableSplitOrJoinOnChangeWithAliasAttribute do
225
+
226
+ it 'should split value when value is set' do
227
+ splittable1 = SplittableSplitOrJoinOnChangeWithAliasAttribute.new(
228
+ email_address: 'splittable@example.com',
229
+ )
230
+
231
+ splittable2 = SplittableSplitOrJoinOnChangeWithAliasAttribute.new
232
+ splittable2.email_address = 'splittable@example.com'
233
+
234
+ [splittable1, splittable2].each do |splittable|
235
+ splittable.email_local.should == 'splittable'
236
+ splittable.email_domain.should == 'example.com'
237
+ end
238
+
239
+ splittable1.email_address = 'splittable1@1.example.com'
240
+
241
+ splittable1.email_local.should == 'splittable1'
242
+ splittable1.email_domain.should == '1.example.com'
243
+ end
244
+
245
+ end
data/spec/models.rb CHANGED
@@ -3,7 +3,7 @@ EMAIL_JOIN_PROCESS = Proc.new{|values| values.join('@') }
3
3
 
4
4
  class Splittable < ActiveRecord::Base
5
5
 
6
- acts_as_splittable
6
+ acts_as_splittable predicates: true
7
7
 
8
8
  splittable :email, split: ['@', 2], partials: [: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/
@@ -43,4 +43,26 @@ class SplittableWithValidationForOriginalColumn < ActiveRecord::Base
43
43
  splittable :email, pattern: EMAIL_SPLIT_PATTERN, on_join: EMAIL_JOIN_PROCESS
44
44
 
45
45
  validates :email, format: { with: /\A[a-zA-Z0-9_.-]+@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,4}\Z/ }
46
+ end
47
+
48
+ class SplittableSplitOrJoinOnChange < ActiveRecord::Base
49
+ self.table_name = 'splittables'
50
+
51
+ acts_as_splittable join_on_change: true, split_on_change: true, callbacks: false
52
+
53
+ splittable :email, pattern: EMAIL_SPLIT_PATTERN, on_join: EMAIL_JOIN_PROCESS
54
+
55
+ splittable :phone_number,
56
+ pattern: /\A(?<phone_number1>\d{3})-(?<phone_number2>\d{4})-(?<phone_number3>\d{4})\Z/,
57
+ on_join: ->(values) { values.join '-' }
58
+ end
59
+
60
+ class SplittableSplitOrJoinOnChangeWithAliasAttribute < ActiveRecord::Base
61
+ self.table_name = 'splittables'
62
+
63
+ acts_as_splittable join_on_change: true, split_on_change: true, callbacks: false
64
+
65
+ splittable :email, pattern: EMAIL_SPLIT_PATTERN, on_join: EMAIL_JOIN_PROCESS
66
+
67
+ alias_attribute :email_address, :email
46
68
  end
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
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - tatat
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-17 00:00:00.000000000 Z
12
+ date: 2013-06-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -89,6 +89,7 @@ files:
89
89
  - Rakefile
90
90
  - acts_as_splittable.gemspec
91
91
  - lib/acts_as_splittable.rb
92
+ - lib/acts_as_splittable/splittable.rb
92
93
  - lib/acts_as_splittable/version.rb
93
94
  - lib/tasks/acts_as_splittable_tasks.rake
94
95
  - spec/database.yml.sample