normatron 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.
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