normatron 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile ADDED
@@ -0,0 +1,191 @@
1
+ h1. Normatron
2
+
3
+ Normatron is an attribute normalizer for ActiveRecord objects.
4
+ With it you can convert attributes to the desired format before saving them in the database.
5
+ This gem inhibits the work of having to override attributes or create a specific method to perform most of the normalizations.
6
+
7
+ h2. Installation
8
+
9
+ Let the bundler install the gem by adding the following into your application gemfile:
10
+
11
+ <pre>gem 'normatron'</pre>
12
+
13
+ And then bundle it up:
14
+
15
+ <pre>$ bundle install</pre>
16
+
17
+ Or install it by yourself:
18
+
19
+ <pre>$ gem install normatron</pre>
20
+
21
+ h2. The problem
22
+
23
+ Suppose you have a product model as the following:
24
+
25
+ <pre>
26
+ # ./db/migrate/20120101010000_create_products.rb
27
+ class CreateProducts < ActiveRecord::Migration
28
+ def change
29
+ create_table :products do |t|
30
+ t.string :name
31
+ t.decimal :price, :precision => 10, :scale => 2
32
+ end
33
+ end
34
+ end
35
+
36
+ # ./app/models/products.rb
37
+ class Product < ActiveRecord::Base
38
+ attr_accessible :name, :price
39
+ end
40
+ </pre>
41
+
42
+ And you want the 'name' attribute be uppercased before saving it into the database.
43
+ The most usual approach to do this includes:
44
+
45
+ * Override the 'name' setter and convert the value to an uppercased string.
46
+ * Use the 'before_validation' callback to run a method or block doing the task.
47
+
48
+ Both ways are ilenegant, boring, error prone and very expensive.
49
+ What led me to make this gem and offer a third way to solve the problem:
50
+
51
+ h2. Usage
52
+
53
+ h3. Single attribute with standard filters
54
+
55
+ <pre>
56
+ # ./app/models/products.rb
57
+ class Product < ActiveRecord::Base
58
+ attr_accessible :name, :price
59
+ normalize :name
60
+ end
61
+
62
+ $ rails console
63
+ > pa = Product.create :name => " memory card "
64
+ > pa.name
65
+ => "memory card"
66
+ > pb = Product.create :name => " "
67
+ > pb.name
68
+ => nil
69
+ </pre>
70
+
71
+ Normatron will use *:squish* and *:blank* filters if no option was given.
72
+
73
+ h3. Multiple filters to a single attribute
74
+
75
+ <pre>normalize :name, :with => [:blank, :squish, :upcase]</pre>
76
+
77
+ Just add the *:with* option and pass the filters as an array.
78
+
79
+ h3. Multiple attributes with same filters
80
+
81
+ <pre>normalize :name, :brand, :with => [:capitalize, :blank]</pre>
82
+
83
+ All symbols outside the *:with* option are flagged as an attribute.
84
+
85
+ h3. Multiple attributes with different filters
86
+
87
+ <pre>
88
+ # ./app/models/user.rb
89
+ class User < ActiveRecord::Base
90
+ attr_accessible :name, :surname, :login, :password, :email
91
+ normalize :name, :surname, :email, :login, :with => [:blank, :squish]
92
+ normalize :name, :surname, :with => :upcase
93
+ normalize :email, :with => :downcase
94
+ end
95
+
96
+ $ rails console
97
+ > u = User.create :name => " c h u c k", :surname => " norris ", :email => "IKillYou@MostBadass.com", :login => "ALLineedislove"
98
+ > u.name
99
+ => "C H U C K"
100
+ > u.surname
101
+ => "NORRIS"
102
+ > u.email
103
+ => "ikillyou@mostbadass.com"
104
+ </pre>
105
+
106
+ You can stack filters to an attribute calling the *normalize* method multiple times.
107
+
108
+ h3. Using custom instance method as a filter
109
+
110
+ <pre>
111
+ # ./app/models/client.rb
112
+ class Client < ActiveRecord::Base
113
+ attr_accessible :name, :phone
114
+
115
+ normalize :phone, :with => :my_phone_filter
116
+
117
+ def my_phone_filter(value)
118
+ digits = value.gsub(/[^\d]/, '')
119
+ "(%s) %s-%s" % [digits[0..1], digits[2..5], digits[6..9]]
120
+ end
121
+ end
122
+
123
+ $ rails console
124
+ > p = Client.create :name => "Jim Raynor", :phone => " a1b c2d e3f g4h i5j k6l m7n o8p q9r s1t "
125
+ > p.phone
126
+ => "(12) 3456-7891"
127
+ </pre>
128
+
129
+ Create an instance method that returns the value as you want. The method must have an unique mandatory parameter.
130
+
131
+ h2. Filters
132
+
133
+ table{border:1px solid black}.
134
+ |_. FILTER|_. INPUT|_.OUTPUT|
135
+ |:blank|"text"|"text"|
136
+ |:blank|" "|nil|
137
+ |:blank|"\n"|nil|
138
+ |:blank|""|nil|
139
+ |:capitalize|"power overwhelming"|"Power overwhelming"|
140
+ |:capitalize|"POWER overwhelming"|"Power overwhelming"|
141
+ |:capitalize|" power overwhelming"|" power overwhelming"|
142
+ |:downcase|"EDWARD"|"edward"|
143
+ |:lstrip|" Chrono Trigger "|"Chrono Trigger "|
144
+ |:rstrip|" Chrono Cross "|" Chrono Cross"|
145
+ |:squish|" "|""|
146
+ |:squish|" \n \r \t \f "|""|
147
+ |:squish|" Master of Puppets "|"Master of Puppets"|
148
+ |:strip|" Final Fantasy "|"Final Fantasy"|
149
+ |:titlecase or :titleize|" system of a down "|" System Of A Down "|
150
+ |:upcase|"text"|"TEXT"|
151
+
152
+ h1. Changelog
153
+
154
+ - 0.0.7 :=
155
+ * Ability to use an instance method as a filter
156
+ =:
157
+
158
+ h1. Contributing
159
+
160
+ * Fork it, add your new features or bug fixes, make your tests and commit.
161
+ * Report any bug or unexpected behavior.
162
+ * Send me your feedback.
163
+ * Pay me a beer. =]
164
+
165
+ h1. Special Thanks
166
+
167
+ This gem was inspired on work of "fnando (fnando's Github)":https://github.com/fnando called "normalize_attributes (normalize_attributes gem)":https://github.com/fnando/normalize_attributes.
168
+ He have a lot of interesting gems on his repo, please take a look.
169
+
170
+ h1. Licence
171
+
172
+ Copyright 2012 Fernando Rodrigues da Silva
173
+
174
+ Permission is hereby granted, free of charge, to any person obtaining
175
+ a copy of this software and associated documentation files (the
176
+ "Software"), to deal in the Software without restriction, including
177
+ without limitation the rights to use, copy, modify, merge, publish,
178
+ distribute, sublicense, and/or sell copies of the Software, and to
179
+ permit persons to whom the Software is furnished to do so, subject to
180
+ the following conditions:
181
+
182
+ The above copyright notice and this permission notice shall be
183
+ included in all copies or substantial portions of the Software.
184
+
185
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
186
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
187
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
188
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
189
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
190
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
191
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/lib/normatron.rb CHANGED
@@ -1,7 +1,19 @@
1
- require "normatron/active_record"
1
+ require "normatron/configuration"
2
+ require "normatron/extensions/active_record"
2
3
 
3
4
  module Normatron
4
- VERSION = "0.0.6"
5
+ VERSION = "0.0.7"
6
+
7
+ class << self
8
+ def configuration
9
+ @configuration ||= Configuration.new
10
+ end
11
+
12
+ def configure
13
+ yield(configuration)
14
+ end
15
+ alias :setup :configure
16
+ end
5
17
  end
6
18
 
7
- ActiveRecord::Base.send :include, Normatron::ActiveRecord
19
+ ActiveRecord::Base.send :include, Normatron::Extensions::ActiveRecord if defined?(ActiveRecord::Base)
@@ -0,0 +1,13 @@
1
+ module Normatron
2
+ class Configuration
3
+ attr_writer :default_filters
4
+
5
+ def initialize
6
+ @default_filters ||= [:squish, :blank]
7
+ end
8
+
9
+ def default_filters
10
+ @default_filters = [@default_filters].flatten.compact.uniq
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,46 @@
1
+ require "normatron/filters/native"
2
+
3
+ module Normatron
4
+ module Extensions
5
+ module ActiveRecord
6
+ def self.included(base)
7
+ base.instance_eval do
8
+ before_validation :apply_normalizations
9
+
10
+ class << self
11
+ attr_accessor :normalize_options
12
+
13
+ def normalize(*args)
14
+ options = args.extract_options!
15
+ options[:with] ||= Normatron.configuration.default_filters
16
+ options[:with] = [options[:with]].flatten
17
+
18
+ @normalize_options ||= {}
19
+ args.each do |attribute|
20
+ @normalize_options[attribute] ||= []
21
+ @normalize_options[attribute] = options[:with]
22
+ end
23
+ @normalize_options
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def apply_normalizations
30
+ self.class.normalize_options.each do |attribute, filters|
31
+ value = send("#{attribute}_before_type_cast") || send(attribute)
32
+
33
+ filters.each do |filter|
34
+ if self.respond_to? filter
35
+ value = send(filter, value)
36
+ else
37
+ value = Normatron::Filters::Native.apply(filter, value)
38
+ end
39
+ end
40
+
41
+ write_attribute attribute, value
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ require "active_support/all"
2
+
3
+ module Normatron
4
+ module Filters
5
+ module Native
6
+ class << self
7
+ def apply(filter, value)
8
+ return value unless value.is_a? String
9
+
10
+ case filter
11
+ when :upcase, :downcase, :capitalize, :titlecase, :titleize
12
+ value.mb_chars.send(filter).to_s
13
+ when :squish, :lstrip, :rstrip, :strip
14
+ value.send(filter)
15
+ when :blank
16
+ send("to_#{filter}", value)
17
+ end
18
+ end
19
+
20
+ def filter_names
21
+ [:upcase, :downcase, :capitalize, :titlecase, :titleize, :squish, :lstrip, :rstrip, :strip, :blank]
22
+ end
23
+
24
+ private
25
+
26
+ def to_blank(value)
27
+ value.blank? ? nil : value
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,45 @@
1
+ require "spec_helper"
2
+
3
+ describe Normatron::Configuration do
4
+
5
+ let(:klass) { Normatron::Configuration }
6
+ let(:instance) { @instance }
7
+
8
+ before :each do
9
+ @instance = klass.new
10
+ end
11
+
12
+ describe :default_filters do
13
+ it "should be initializated" do
14
+ instance.default_filters.should eq [:squish, :blank]
15
+ end
16
+
17
+ it "should be enclause values into an array" do
18
+ instance.default_filters = :a
19
+ instance.default_filters.should eq [:a]
20
+ end
21
+
22
+ it "should reject repeated filters" do
23
+ instance.default_filters = :a, :a
24
+ instance.default_filters.should eq [:a]
25
+
26
+ instance.default_filters += [:a, :b]
27
+ instance.default_filters.should eq [:a, :b]
28
+ end
29
+
30
+ it "should reject nil filters" do
31
+ instance.default_filters = nil
32
+ instance.default_filters.should eq []
33
+
34
+ instance.default_filters = :a, nil
35
+ instance.default_filters.should eq [:a]
36
+
37
+ instance.default_filters << nil
38
+ instance.default_filters.should eq [:a]
39
+ end
40
+ end
41
+
42
+ pending "should map filter modules"
43
+ pending "should allow create inline filters"
44
+ pending "should"
45
+ end
@@ -0,0 +1,112 @@
1
+ require "spec_helper"
2
+
3
+ describe Normatron::Extensions::ActiveRecord do
4
+ let(:model_class) { Client }
5
+
6
+ before :each do
7
+ model_class.normalize_options = {}
8
+ end
9
+
10
+ it "should allow get and set normalization options" do
11
+ model_class.normalize(:name, :cpf, with: [:a, :b]).should include(name: [:a, :b], cpf: [:a, :b])
12
+ model_class.normalize_options.should include(name: [:a, :b], cpf: [:a, :b])
13
+ end
14
+
15
+ it "should allow set multiple attributes" do
16
+ model_class.normalize(:name, :cpf, :phone)
17
+ model_class.normalize_options.should include(:name, :cpf, :phone)
18
+ end
19
+
20
+ it "should allow include single filter" do
21
+ model_class.normalize(:name, with: :a)
22
+ model_class.normalize_options.should include(name: [:a])
23
+ end
24
+
25
+ it "should allow include multiple filters" do
26
+ model_class.normalize(:name, with: [:a, :b])
27
+ model_class.normalize_options.should include(name: [:a, :b])
28
+ end
29
+
30
+ it "should include default filters" do
31
+ model_class.normalize(:name)
32
+ model_class.normalize_options.should include(name: [:squish, :blank])
33
+ end
34
+
35
+ it "should apply normalizations" do
36
+ model_class.normalize(:name)
37
+ instance = model_class.new
38
+ instance.name = " xxx "
39
+ instance.apply_normalizations
40
+ instance.name.should eq "xxx"
41
+
42
+ class Client < ActiveRecord::Base
43
+ def my_filter(value)
44
+ value.split(//) * "-"
45
+ end
46
+ end
47
+
48
+ model_class.normalize(:name, with: :my_filter)
49
+ instance = model_class.new
50
+ instance.name = "xxx"
51
+ instance.apply_normalizations
52
+ instance.name.should eq "x-x-x"
53
+ end
54
+
55
+ pending "should apply default normalizations when :with is ommited"
56
+ pending "should apply instance methods normalizations"
57
+ pending "should apply blocks normalizations"
58
+ pending "should apply modules normalizations"
59
+ pending "should apply configuration blocks normalizations"
60
+
61
+ pending "should set default normalization filters" do
62
+ pending "to single attribute"
63
+ pending "to multiple attributes"
64
+ end
65
+ pending "should set single normalization filter" do
66
+ pending "to single attribute"
67
+ pending "to multiple attributes"
68
+ end
69
+ pending "should set multiple normalization filters" do
70
+ pending "to single attribute"
71
+ pending "to multiple attributes"
72
+ end
73
+ pending "should remove repeated normalization" do
74
+ pending "attributes"
75
+ pending "filters"
76
+ end
77
+ pending "should remove nil normalization" do
78
+ pending "attributes"
79
+ pending "filters"
80
+ end
81
+ pending "should ignore nil normalization" do
82
+ pending "attribute"
83
+ pending "filter"
84
+ end
85
+ pending "should apply normalizations" do
86
+ pending "using a single filter" do
87
+ pending "for a single attribute"
88
+ pending "for all attributes"
89
+ end
90
+ pending "using multiple filters" do
91
+ pending "for a single attribute"
92
+ pending "for all attributes"
93
+ end
94
+ pending "specified into" do
95
+ pending "native filters module"
96
+ pending "custom filters module"
97
+ pending "instance model"
98
+ pending "instance block"
99
+ pending "instance lambda"
100
+ pending "configuration lambda"
101
+ end
102
+ end
103
+ pending "should allow specify" do
104
+ pending "when the normalizations will be done"
105
+ pending "conditions to normalizations be done"
106
+ pending "sequence of normalization chain"
107
+ end
108
+ pending "should raise exception" do
109
+ pending "when given attribute doesn't exist"
110
+ pending "when given filter doesn't exist"
111
+ end
112
+ end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+
3
+ describe Normatron do
4
+ let(:mod) { Normatron }
5
+ let(:config) { Normatron.configuration }
6
+
7
+ describe "configuration" do
8
+ it "should respond to aliases" do
9
+ mod.should respond_to :configuration
10
+ mod.should respond_to :configure
11
+ mod.should respond_to :setup
12
+ end
13
+
14
+ it "should return configuration object" do
15
+ config.should be_an_instance_of Normatron::Configuration
16
+ end
17
+
18
+ it "should process given blocks" do
19
+ expect { |b| Normatron.setup(&b) }.to yield_control
20
+ end
21
+ end
22
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  require "rspec"
2
+ require "active_record"
2
3
  require "normatron"
3
4
 
4
5
  ActiveRecord::Base.establish_connection :adapter => "sqlite3", :database => ":memory:"
5
-
6
-
7
-
8
6
  Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each { |f| require f }
@@ -0,0 +1,3 @@
1
+ class Client < ActiveRecord::Base
2
+ attr_accessible :name, :credit_limit, :cpf, :birth_date, :phone, :login_count
3
+ end
@@ -1,6 +1,10 @@
1
1
  ActiveRecord::Schema.define(:version => 0) do
2
- create_table :test_models do |t|
3
- t.string :string_column
4
- t.integer :integer_column
2
+ create_table :clients do |t|
3
+ t.string :name
4
+ t.decimal :credit_limit, precision: 10, scale: 2
5
+ t.string :cpf
6
+ t.date :birth_date
7
+ t.string :phone
8
+ t.integer :login_count
5
9
  end
6
10
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: normatron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-02 00:00:00.000000000 Z
12
+ date: 2012-09-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -62,24 +62,26 @@ dependencies:
62
62
  description: ! " Normatron is an attribute normalizer for ActiveRecord objects.\n
63
63
  \ With it you can convert attributes to the desired format before saving them
64
64
  in the database.\n This gem inhibits the work of having to override attributes
65
- or create a specific method to perform the normalizations.\n"
65
+ or create a specific method to perform most of the normalizations.\n"
66
66
  email:
67
67
  - fernandors87@gmail.com
68
68
  executables: []
69
69
  extensions: []
70
70
  extra_rdoc_files: []
71
71
  files:
72
- - lib/normatron/filters.rb
73
- - lib/normatron/active_record.rb
74
72
  - lib/normatron.rb
73
+ - lib/normatron/configuration.rb
74
+ - lib/normatron/filters/native.rb
75
+ - lib/normatron/extensions/active_record.rb
75
76
  - MIT-LICENSE
76
77
  - Rakefile
77
- - README.rdoc
78
- - spec/support/test_model.rb
79
- - spec/support/schema.rb
80
- - spec/active_record_spec.rb
81
- - spec/filters_spec.rb
78
+ - README.textile
79
+ - spec/lib/normatron/configuration_spec.rb
80
+ - spec/lib/normatron/extensions/active_record_spec.rb
81
+ - spec/lib/normatron_spec.rb
82
82
  - spec/spec_helper.rb
83
+ - spec/support/client_model.rb
84
+ - spec/support/schema.rb
83
85
  homepage: https://github.com/fernandors87/normatron
84
86
  licenses: []
85
87
  post_install_message:
@@ -105,8 +107,9 @@ signing_key:
105
107
  specification_version: 3
106
108
  summary: Normalize attributes for ActiveRecord objects.
107
109
  test_files:
108
- - spec/support/test_model.rb
109
- - spec/support/schema.rb
110
- - spec/active_record_spec.rb
111
- - spec/filters_spec.rb
110
+ - spec/lib/normatron/configuration_spec.rb
111
+ - spec/lib/normatron/extensions/active_record_spec.rb
112
+ - spec/lib/normatron_spec.rb
112
113
  - spec/spec_helper.rb
114
+ - spec/support/client_model.rb
115
+ - spec/support/schema.rb
data/README.rdoc DELETED
@@ -1,197 +0,0 @@
1
- = Normatron
2
-
3
- Normatron is an attribute normalizer for Ruby On Rails ActiveRecord objects.
4
- With it you can convert attributes to the desired format before saving them in the database.
5
- This gem inhibits the work of having to override attributes or create a specific method to perform the normalizations.
6
-
7
- = Installation
8
- Let the bundler install the gem by adding the following into your application gemfile:
9
- gem 'normatron'
10
-
11
- And then bundle it up:
12
- $ bundle install
13
-
14
- Or install it by yourself:
15
- $ gem install normatron
16
-
17
- = The problem
18
- Suppose you have a product model as the following:
19
- # ./db/migrate/20120101010000_create_products.rb
20
- class CreateProducts < ActiveRecord::Migration
21
- def change
22
- create_table :products do |t|
23
- t.string :name
24
- t.decimal :price, :precision => 10, :scale => 2
25
- end
26
- end
27
- end
28
-
29
- # ./app/models/products.rb
30
- class Product < ActiveRecord::Base
31
- attr_accessible :name, :price
32
- end
33
-
34
- And you want the 'name' attribute be uppercased before saving it into the database.
35
- The most usual approach to do it includes:
36
- * Override the 'name' setter and convert the value to an uppercased string.
37
- * Use the 'before_validation' callback to run a method or block doing the task.
38
- Both ways are ilenegant, boring, error prone and very expensive.
39
- What led me to make this gem and offer a third way to solve the problem:
40
-
41
- = Usage
42
- # ./app/models/products.rb
43
- class Product < ActiveRecord::Base
44
- attr_accessible :name, :price
45
-
46
- normalize :name, :with => :upcase
47
- end
48
-
49
- $ rails console
50
- > p = Product.create :name => " memory card "
51
- > p.name
52
- => " MEMORY CARD "
53
-
54
- You can also assign multiple attributes to the same filter:
55
- normalize :name, :brand, :with => :capitalize
56
-
57
- And multiple filters to an unique attribute:
58
- normalize :email, :with => [:downcase, :squish]
59
-
60
- Or mixing both:
61
- normalize :name, :description, :with => [:upcase, :squish, :blank]
62
-
63
- = Filters
64
- == :upcase and :downcase
65
- Change all character to upcase and downcase, respectively.
66
- Accented characters are affected too.
67
-
68
- class User < ActiveRecord::Base
69
- attr_accessible :name
70
-
71
- normalize :name, :with => :upcase
72
- end
73
-
74
- $ rails console
75
- > d = User.create :name => "Darth Vader"
76
- > d.name
77
- => "DARTH VADER"
78
- > j = User.create :name => " José Negrão "
79
- > j.name
80
- => " JOSÉ NEGRÃO "
81
-
82
- == :capitalize
83
- Capitalize the first character of the sequence.
84
- Accented characters are affected too.
85
-
86
- class Player < ActiveRecord::Base
87
- attr_accessible :name, :race
88
-
89
- normalize :name, :race, :with => :capitalize
90
- end
91
-
92
- $ rails console
93
- > a = Player.create :name => "ÉBANO PEREIRA", :race => " protoss"
94
- > a.name
95
- => "Ébano pereira"
96
- > a.race
97
- => " protoss"
98
-
99
- == :titlecase or :titleize
100
- Capitalize the first character of each word.
101
- Accented characters are affected too.
102
-
103
- class Player < ActiveRecord::Base
104
- attr_accessible :name, :race
105
-
106
- normalize :name, :race, :with => :titleize
107
- end
108
-
109
- $ rails console
110
- > a = Player.create :name => "fernando rodrigues", :race => " zerg"
111
- > a.name
112
- => "Fernando Rodrigues"
113
- > a.race
114
- => " Zerg"
115
-
116
- == :strip, :lstrip and :rstrip
117
- Remove trailing and/or leading spaces.
118
-
119
- class Address < ActiveRecord::Base
120
- attr_accessible :city, :district, :street
121
-
122
- normalize :city, :with => :strip
123
- normalize :district, :with => :lstrip
124
- normalize :street, :with => :rstrip
125
- end
126
-
127
- $ rails console
128
- > a = Address.create :city => " gotham ", :district => " red light ", :street => " no name "
129
- > a.city
130
- => "gotham"
131
- > a.district
132
- => "red light "
133
- > a.street
134
- => " no name"
135
-
136
- == :squish
137
- Remove trailing and leading spaces and then changing remaining consecutive whitespace groups into one space each.
138
-
139
- class Product < ActiveRecord::Base
140
- attr_accessible :description
141
-
142
- normalize :description, :with => :squish
143
- end
144
-
145
- $ rails console
146
- > p = Product.create :description => " \t My product is \n cheap! ! ! "
147
- > p.description
148
- => "My product is cheap!!!"
149
-
150
- == :blank
151
- Convert a blank attribute into nil.
152
-
153
- class Person < ActiveRecord::Base
154
- attr_accessible :gender, :name
155
-
156
- normalize :gender, :with => :blank
157
- end
158
-
159
- $ rails console
160
- > p = Person.create :gender => " ", :name => " "
161
- > p.gender
162
- => nil
163
- > p.name
164
- => " "
165
-
166
- = Contributing
167
- * Fork it, add your new features or bug fixes, make your tests and commit.
168
- * Report any bug or unexpected behavior.
169
- * Send me your feedback.
170
- * Pay me a beer. =]
171
-
172
- = Special Thanks
173
- This gem was inspired on work of {fnando}[https://github.com/fnando] called {normalize_attributes}[https://github.com/fnando/normalize_attributes].
174
- I just forked his gem and added some functionalities.<br>
175
- He has a lot of interesting gems on his repo, please take a look.
176
-
177
- = Licence
178
- Copyright 2012 Fernando Rodrigues da Silva
179
-
180
- Permission is hereby granted, free of charge, to any person obtaining
181
- a copy of this software and associated documentation files (the
182
- "Software"), to deal in the Software without restriction, including
183
- without limitation the rights to use, copy, modify, merge, publish,
184
- distribute, sublicense, and/or sell copies of the Software, and to
185
- permit persons to whom the Software is furnished to do so, subject to
186
- the following conditions:
187
-
188
- The above copyright notice and this permission notice shall be
189
- included in all copies or substantial portions of the Software.
190
-
191
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
192
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
193
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
194
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
195
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
196
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
197
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,55 +0,0 @@
1
- require "normatron/filters"
2
- require "active_record"
3
-
4
- module Normatron
5
- module ActiveRecord
6
- def self.included(base)
7
- base.instance_eval do
8
- before_validation :apply_normalization
9
-
10
- class << self
11
- attr_accessor :normalization_filters
12
-
13
- def normalize(*args)
14
- options = args.extract_options!
15
- options[:with] ||= [:blank, :squish]
16
-
17
- filters = [options[:with]].flatten.compact
18
- filters.map!(&:to_sym)
19
- intersect = filters & (Filters.filter_names + methods(false))
20
-
21
- unless intersect == filters
22
- raise "Normalization filters #{filters - intersect} doesn't exist"
23
- end
24
-
25
- @normalization_filters ||= {}
26
- args.each do |raw_attribute|
27
- attribute = raw_attribute.to_sym
28
-
29
- if self.column_names.include? attribute.to_s
30
- @normalization_filters[attribute] ||= []
31
- @normalization_filters[attribute] += filters
32
- else
33
- raise "Attribute '#{attribute}' doesn't exist in #{self}"
34
- end
35
- end
36
- end
37
- end
38
- end
39
- end
40
-
41
- def apply_normalization
42
- return unless self.class.normalization_filters.is_a? Hash
43
-
44
- self.class.normalization_filters.each do |attribute, filters|
45
- value = send("#{attribute}_before_type_cast") || send(attribute)
46
-
47
- filters.each do |filter|
48
- value = Filters.apply(filter, value)
49
- end
50
-
51
- write_attribute attribute, value
52
- end
53
- end
54
- end
55
- end
@@ -1,71 +0,0 @@
1
- require "active_support/all"
2
-
3
- module Normatron
4
- module Filters
5
- class << self
6
- def apply(filter, value)
7
- return value unless value.is_a? String
8
-
9
- case filter
10
- when :upcase, :downcase, :capitalize, :titlecase, :titleize
11
- value.mb_chars.send(filter).to_s
12
- when :squish, :lstrip, :rstrip, :strip
13
- value.send(filter)
14
- when :blank
15
- send("to_#{filter}", value)
16
- end
17
- end
18
-
19
- def filter_names
20
- [:upcase, :downcase, :capitalize, :titlecase, :titleize, :squish, :lstrip, :rstrip, :strip, :blank]
21
- end
22
-
23
- private
24
-
25
- def to_blank(value)
26
- value.blank? ? nil : value
27
- end
28
- end
29
-
30
- =begin
31
- def self.filter_currency(value)
32
- filter_number value, :currency
33
- end
34
-
35
- def self.filter_float(value)
36
- filter_number value, :float
37
- end
38
-
39
- def self.filter_integer(value)
40
- filter_number value
41
- end
42
-
43
- def self.filter_number(value, type = :integer)
44
- return value unless value.is_a?(String) && value.present?
45
-
46
- # Find the first number in the sequence
47
- first_number_position = value.index(/\d/)
48
- return unless first_number_position # Do nothing if it's don't have any number
49
-
50
- # Is a negative number?
51
- negative = value[0..first_number_position].include?("-")
52
-
53
- # Decimal separator on the current locale
54
- separator = I18n.t "number#{ '.currency' if type == :currency }.format.separator"
55
-
56
- # Amount of decimal places
57
- separator_position = value.rindex(separator)
58
- chars_until_separator = separator_position + 1 rescue value.size
59
- decimal_places = value.size - chars_until_separator
60
-
61
- # Build number
62
- res = filter_digits(value).to_f
63
- res *= -1 if negative
64
- res /= 10 ** decimal_places
65
- res = res.to_i if type == :integer
66
-
67
- res
68
- end
69
- =end
70
- end
71
- end
@@ -1,137 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Normatron::ActiveRecord do
4
- before :each do
5
- TestModel.normalization_filters = nil
6
- end
7
-
8
- it "filters should be accessible" do
9
- TestModel.normalize :string_column, :with => [:capitalize, :upcase]
10
- TestModel.normalize :integer_column, :with => :blank
11
- TestModel.normalization_filters.should == { :string_column => [:capitalize, :upcase],
12
- :integer_column => [:blank] }
13
- TestModel.normalization_filters.delete :string_column
14
- TestModel.normalization_filters.should == { :integer_column => [:blank] }
15
- end
16
-
17
- it "should save without normalization" do
18
- lambda do
19
- instance = TestModel.new :string_column => "Any string"
20
- instance.save!
21
- end.should_not raise_error
22
- end
23
-
24
- it "should skip normalization when filters aren't a Hash" do
25
- TestModel.normalization_filters = true
26
- lambda do
27
- instance = TestModel.new :string_column => "Any string"
28
- instance.valid?
29
- end.should_not raise_error
30
-
31
- TestModel.normalization_filters = 1
32
- lambda do
33
- instance = TestModel.new :string_column => "Any string"
34
- instance.valid?
35
- end.should_not raise_error
36
-
37
- TestModel.normalization_filters = false
38
- lambda do
39
- instance = TestModel.new :string_column => "Any string"
40
- instance.valid?
41
- end.should_not raise_error
42
- end
43
-
44
- it "should apply default filter to single attribute" do
45
- TestModel.normalize :string_column
46
- TestModel.normalization_filters.should == { :string_column => [:blank, :squish] }
47
- end
48
-
49
- it "should apply default filter to multiple attributes" do
50
- TestModel.normalize :string_column, :integer_column
51
- TestModel.normalization_filters.should == { :string_column => [:blank, :squish],
52
- :integer_column => [:blank, :squish] }
53
- end
54
-
55
- it "should apply single filter to single attribute" do
56
- TestModel.normalize :string_column, :with => :upcase
57
- TestModel.normalization_filters.should == { :string_column => [:upcase] }
58
- end
59
-
60
- it "should apply single filter to multiple attributes" do
61
- TestModel.normalize :string_column, :integer_column, :with => :blank
62
- TestModel.normalization_filters.should == { :string_column => [:blank],
63
- :integer_column => [:blank] }
64
- end
65
-
66
- it "should apply multiple filters to single attribute" do
67
- TestModel.normalize :string_column, :with => [:blank, :upcase]
68
- TestModel.normalization_filters.should == { :string_column => [:blank, :upcase] }
69
- end
70
-
71
- it "should apply multiple filters to multiple attributes" do
72
- TestModel.normalize :string_column, :integer_column, :with => [:squish, :blank]
73
- TestModel.normalization_filters.should == { :string_column => [:squish, :blank],
74
- :integer_column => [:squish, :blank] }
75
- end
76
-
77
- it "should stack filters for the same attribute" do
78
- TestModel.normalize :string_column, :with => [:upcase, :squish]
79
- TestModel.normalize :string_column, :integer_column, :with => :blank
80
- TestModel.normalize :string_column, :integer_column, :with => [:downcase, :strip]
81
- TestModel.normalization_filters.should == { :string_column => [:upcase, :squish, :blank, :downcase, :strip],
82
- :integer_column => [:blank, :downcase, :strip] }
83
- end
84
-
85
- it "should apply attributes as string" do
86
- TestModel.normalize "string_column", :with => :upcase
87
-
88
- instance = TestModel.new :string_column => "Any string"
89
- instance.valid?
90
- instance.string_column.should == "ANY STRING"
91
-
92
- TestModel.normalization_filters.should == { :string_column => [:upcase] }
93
- end
94
-
95
- it "should apply filters as one word string" do
96
- TestModel.normalize :string_column, :with => "upcase"
97
-
98
- TestModel.normalization_filters.should == { :string_column => [:upcase] }
99
-
100
- instance = TestModel.new :string_column => "Any string"
101
- instance.valid?
102
- instance.string_column.should == "ANY STRING"
103
- end
104
-
105
- it "should raise error when a wrong filter is used" do
106
- lambda do
107
- TestModel.normalize :string_column, :with => :wrong_filter
108
- end.should raise_error "Normalization filters [:wrong_filter] doesn't exist"
109
- end
110
-
111
- it "should raise error when a wrong attribute is used" do
112
- lambda do
113
- TestModel.normalize :wrong_column, :with => :upcase
114
- end.should raise_error "Attribute 'wrong_column' doesn't exist in TestModel"
115
- end
116
-
117
- pending "should allow use an instance method as a filter" do
118
- lambda do
119
- TestModel.normalize :string_column, :with => :my_custom_filter_method
120
- end.should_not raise_error "Normalization filters [:my_custom_filter_method] doesn't exist"
121
-
122
- TestModel.normalization_filters.should == { :string_column => [:my_custom_filter_method] }
123
- end
124
-
125
- pending "should apply an instance method used as a filter" do
126
- TestModel.normalize :string_column, :with => :my_custom_filter_method
127
-
128
- m = TestModel.new :string_column => "My life for Aiur"
129
- m.string_column.should == "M-y- -l-i-f-e- -f-o-r- -A-i-u-r"
130
- end
131
-
132
- pending "should allow change default callback"
133
- pending "should allow get value after type cast"
134
- pending "should allow use blocks"
135
- pending "should allow build custom filters"
136
- pending "should allow use a instance method as a filter"
137
- end
data/spec/filters_spec.rb DELETED
@@ -1,218 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require "spec_helper"
4
-
5
- describe Normatron::Filters do
6
-
7
- before :each do
8
- TestModel.normalization_filters = nil
9
- end
10
-
11
- it :blank do
12
- value = nil
13
- expected = nil
14
- Normatron::Filters.apply(:blank, value).should == expected
15
-
16
- value = " abc \f DEF \n 123 áÈç \t !*& \r 4gü "
17
- expected = " abc \f DEF \n 123 áÈç \t !*& \r 4gü "
18
- Normatron::Filters.apply(:blank, value).should == expected
19
-
20
- value = " "
21
- expected = nil
22
- Normatron::Filters.apply(:blank, value).should == expected
23
-
24
- value = ""
25
- expected = nil
26
- Normatron::Filters.apply(:blank, value).should == expected
27
- end
28
-
29
- it :capitalize do
30
- value = nil
31
- expected = nil
32
- Normatron::Filters.apply(:capitalize, value).should == expected
33
-
34
- value = " abc \f DEF \n 123 áÈç \t !*& \r 4gü "
35
- expected = " abc \f def \n 123 áèç \t !*& \r 4gü "
36
- Normatron::Filters.apply(:capitalize, value).should == expected
37
-
38
- value = "abc \f DEF \n 123 áÈç \t !*& \r 4gü"
39
- expected = "Abc \f def \n 123 áèç \t !*& \r 4gü"
40
- Normatron::Filters.apply(:capitalize, value).should == expected
41
- end
42
-
43
- it :downcase do
44
- value = nil
45
- expected = nil
46
- Normatron::Filters.apply(:downcase, value).should == expected
47
-
48
- value = " abc \f DEF \n 123 áÈç \t !*& \r 4gü "
49
- expected = " abc \f def \n 123 áèç \t !*& \r 4gü "
50
- Normatron::Filters.apply(:downcase, value).should == expected
51
- end
52
-
53
- it :lstrip do
54
- value = nil
55
- expected = nil
56
- Normatron::Filters.apply(:lstrip, value).should == expected
57
-
58
- value = " abc \f DEF \n 123 áÈç \t !*& \r 4gü "
59
- expected = "abc \f DEF \n 123 áÈç \t !*& \r 4gü "
60
- Normatron::Filters.apply(:lstrip, value).should == expected
61
- end
62
-
63
- it :rstrip do
64
- value = nil
65
- expected = nil
66
- Normatron::Filters.apply(:rstrip, value).should == expected
67
-
68
- value = " abc \f DEF \n 123 áÈç \t !*& \r 4gü "
69
- expected = " abc \f DEF \n 123 áÈç \t !*& \r 4gü"
70
- Normatron::Filters.apply(:rstrip, value).should == expected
71
- end
72
-
73
- it :squish do
74
- value = nil
75
- expected = nil
76
- Normatron::Filters.apply(:squish, value).should == expected
77
-
78
- value = " abc \f DEF \n 123 áÈç \t !*& \r 4gü "
79
- expected = "abc DEF 123 áÈç !*& 4gü"
80
- Normatron::Filters.apply(:squish, value).should == expected
81
- end
82
-
83
- it :strip do
84
- value = nil
85
- expected = nil
86
- Normatron::Filters.apply(:strip, value).should == expected
87
-
88
- value = " abc \f DEF \n 123 áÈç \t !*& \r 4gü "
89
- expected = "abc \f DEF \n 123 áÈç \t !*& \r 4gü"
90
- Normatron::Filters.apply(:strip, value).should == expected
91
- end
92
-
93
- it :titlecase do
94
- value = nil
95
- expected = nil
96
- Normatron::Filters.apply(:titlecase, value).should == expected
97
- Normatron::Filters.apply(:titleize, value).should == expected
98
-
99
- value = " abc \f DEF \n 123 áÈç \t !*& \r 4gü "
100
- expected = " Abc \f Def \n 123 Áèç \t !*& \r 4gü "
101
- Normatron::Filters.apply(:titlecase, value).should == expected
102
- Normatron::Filters.apply(:titleize, value).should == expected
103
- end
104
-
105
- it :upcase do
106
- value = nil
107
- expected = nil
108
- Normatron::Filters.apply(:upcase, value).should == expected
109
-
110
- value = " abc \f DEF \n 123 áÈç \t !*& \r 4gü "
111
- expected = " ABC \f DEF \n 123 ÁÈÇ \t !*& \r 4GÜ "
112
- Normatron::Filters.apply(:upcase, value).should == expected
113
- end
114
-
115
- pending "singularize"
116
- pending "pluralize"
117
- pending "parameterize"
118
- pending "humanize"
119
- pending "upper_camelcase"
120
- pending "lower_camelcase"
121
- pending "classify"
122
- pending "dasherize"
123
- pending "deconstantize"
124
- pending "demodulize"
125
- pending "html_safe"
126
- pending "constantize"
127
- pending "tableize"
128
- pending "underscore"
129
- =begin
130
- it :singularize do
131
- value = nil
132
- expected = nil
133
- Normatron::Filters.apply(:singularize, value).should == expected
134
-
135
- value = "products"
136
- expected = "product"
137
- Normatron::Filters.apply(:singularize, value).should == expected
138
- end
139
-
140
- it :pluralize do
141
- value = nil
142
- expected = nil
143
- Normatron::Filters.apply(:pluralize, value).should == expected
144
-
145
- value = "product"
146
- expected = "products"
147
- Normatron::Filters.apply(:pluralize, value).should == expected
148
- end
149
-
150
- it :parameterize do
151
- value = nil
152
- expected = nil
153
- Normatron::Filters.apply(:parameterize, value).should == expected
154
-
155
- value = " abc \f DEF \n 123 áÈç \t !*& \r 4gü "
156
- expected = "abc-def-123-aec-4gu"
157
- Normatron::Filters.apply(:parameterize, value).should == expected
158
- end
159
-
160
- it :humanize do
161
- value = nil
162
- expected = nil
163
- Normatron::Filters.apply(:humanize, value).should == expected
164
-
165
- value = "éou_shall_not_pass"
166
- expected = "Éou_shall_not_pass"
167
- Normatron::Filters.apply(:humanize, value).should == expected
168
- end
169
-
170
- it :upper_camelcase do
171
- value = nil
172
- expected = nil
173
- Normatron::Filters.apply(:camelize, value).should == expected
174
- Normatron::Filters.apply(:camelcase, value).should == expected
175
- Normatron::Filters.apply(:upper_camelize, value).should == expected
176
- Normatron::Filters.apply(:upper_camelcase, value).should == expected
177
-
178
- value = "active_record/érrors"
179
- expected = "ActiveRecord::Érrors"
180
- Normatron::Filters.apply(:camelize, value).should == expected
181
- Normatron::Filters.apply(:camelcase, value).should == expected
182
- Normatron::Filters.apply(:upper_camelize, value).should == expected
183
- Normatron::Filters.apply(:upper_camelcase, value).should == expected
184
- end
185
-
186
- it :lower_camelcase do
187
- value = nil
188
- expected = nil
189
- Normatron::Filters.apply(:lower_camelize, value).should == expected
190
- Normatron::Filters.apply(:lower_camelcase, value).should == expected
191
-
192
- value = "active_record/érrors"
193
- expected = "activeRecord::Érrors"
194
- Normatron::Filters.apply(:lower_camelize, value).should == expected
195
- Normatron::Filters.apply(:lower_camelcase, value).should == expected
196
- end
197
-
198
- it :classify do
199
- value = nil
200
- expected = nil
201
- Normatron::Filters.apply(:classify, value).should == expected
202
-
203
- value = "áctive_record/errors"
204
- expected = "ÁctiveRecord::Errors"
205
- Normatron::Filters.apply(:classify, value).should == expected
206
- end
207
-
208
- it :dasherize do
209
- value = nil
210
- expected = nil
211
- Normatron::Filters.apply(:dasherize, value).should == expected
212
-
213
- value = "active_record/errors"
214
- expected = "active-record/errors"
215
- Normatron::Filters.apply(:dasherize, value).should == expected
216
- end
217
- =end
218
- end
@@ -1,7 +0,0 @@
1
- class TestModel < ActiveRecord::Base
2
- attr_accessible :string_column, :integer_column
3
-
4
- def my_custom_filter_method(value)
5
- value.split(//) * "-"
6
- end
7
- end