acts_as_splittable 0.0.4 → 0.0.5

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: 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