formatted_attributes 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,66 @@
1
- require "active_record"
2
- require "formatted_attributes/active_record"
3
- require "formatted_attributes/version"
1
+ # frozen_string_literal: true
4
2
 
5
- ActiveRecord::Base.send :include, FormattedAttributes::ActiveRecord
3
+ module FormattedAttributes
4
+ require "formatted_attributes/version"
5
+
6
+ def self.included(base)
7
+ base.instance_eval do
8
+ extend ClassMethods
9
+ end
10
+ end
11
+
12
+ module ClassMethods
13
+ def formatted(*args)
14
+ options = args.extract_options!
15
+ formatter = options[:with]
16
+
17
+ extension = Module.new do
18
+ args.each do |attr|
19
+ formatted_attr = :"@formatted_#{attr}"
20
+
21
+ # Overwrite attribute setter.
22
+ # This will clear the formatted attribute's cache.
23
+ #
24
+ # The reason we're using `prepend extension` is that ActiveRecord's
25
+ # attributes aren't defined upfront, so we can't retrieve a method
26
+ # reference with `instance_method(attr)` to use on this overwriting
27
+ # method, forcing us to call `super` instead. The downside of this
28
+ # approach is that each attribute will include a new module, but for
29
+ # most cases that won't be a problem.
30
+ define_method("#{attr}=") do |value|
31
+ instance_variable_set(formatted_attr, nil)
32
+ super(value)
33
+ end
34
+
35
+ # Create the formatted attribute reader.
36
+ # This method will read the raw value and convert it to the formatted
37
+ # value by calling `format_to_{formatter}`.
38
+ define_method("formatted_#{attr}") do
39
+ formatted_value = instance_variable_get(formatted_attr)
40
+
41
+ return formatted_value if formatted_value
42
+
43
+ instance_variable_set(
44
+ formatted_attr,
45
+ send(:"convert_with_#{formatter}", send(attr))
46
+ )
47
+ end
48
+
49
+ # Create the formatted attribute setter.
50
+ # This method will receive a formatted value and coerce it into the
51
+ # expected format by calling `format_from_{formatter}`.
52
+ define_method("formatted_#{attr}=") do |formatted_value|
53
+ send(
54
+ :"#{attr}=",
55
+ send(:"convert_from_#{formatter}", formatted_value)
56
+ )
57
+ end
58
+ end
59
+ end
60
+
61
+ prepend extension
62
+ end
63
+
64
+ alias formatted_attribute formatted
65
+ end
66
+ end
metadata CHANGED
@@ -1,144 +1,212 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: formatted_attributes
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 1
8
- - 0
9
- version: 0.1.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
10
5
  platform: ruby
11
- authors:
6
+ authors:
12
7
  - Nando Vieira
13
- autorequire:
14
- bindir: bin
8
+ autorequire:
9
+ bindir: exe
15
10
  cert_chain: []
16
-
17
- date: 2010-11-06 00:00:00 -02:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
11
+ date: 2022-01-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: actionpack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
21
28
  name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
22
35
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 0
30
- version: "0"
31
- type: :runtime
32
- version_requirements: *id001
33
- - !ruby/object:Gem::Dependency
34
- name: rspec
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
35
49
  prerelease: false
36
- requirement: &id002 !ruby/object:Gem::Requirement
37
- none: false
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- segments:
42
- - 2
43
- - 0
44
- - 0
45
- version: 2.0.0
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-utils
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
46
62
  type: :development
47
- version_requirements: *id002
48
- - !ruby/object:Gem::Dependency
49
- name: sqlite3-ruby
50
63
  prerelease: false
51
- requirement: &id003 !ruby/object:Gem::Requirement
52
- none: false
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- segments:
57
- - 0
58
- version: "0"
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-meta
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
59
90
  type: :development
60
- version_requirements: *id003
61
- - !ruby/object:Gem::Dependency
62
- name: actionpack
63
91
  prerelease: false
64
- requirement: &id004 !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- segments:
70
- - 0
71
- version: "0"
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
72
104
  type: :development
73
- version_requirements: *id004
74
- - !ruby/object:Gem::Dependency
75
- name: ruby-debug19
76
105
  prerelease: false
77
- requirement: &id005 !ruby/object:Gem::Requirement
78
- none: false
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- segments:
83
- - 0
84
- version: "0"
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-fnando
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
85
118
  type: :development
86
- version_requirements: *id005
87
- description: Sometimes you need to expose a helper method that will convert its value before saving it to the database. This gem will add `formatted_` suffix to the attributes you specify.
88
- email:
89
- - fnando.vieira@gmail.com
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: sqlite3
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: Add methods that format attributes from/to helper methods.
154
+ email:
155
+ - me@fnando.com
90
156
  executables: []
91
-
92
157
  extensions: []
93
-
94
158
  extra_rdoc_files: []
95
-
96
- files:
97
- - .gitignore
159
+ files:
160
+ - ".github/CODEOWNERS"
161
+ - ".github/FUNDING.yml"
162
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
163
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
164
+ - ".github/PULL_REQUEST_TEMPLATE.md"
165
+ - ".github/dependabot.yml"
166
+ - ".github/workflows/ruby-tests.yml"
167
+ - ".gitignore"
168
+ - ".rspec"
169
+ - ".rubocop.yml"
170
+ - CHANGELOG.md
171
+ - CODE_OF_CONDUCT.md
172
+ - CONTRIBUTING.md
98
173
  - Gemfile
99
- - Gemfile.lock
100
- - README.rdoc
174
+ - LICENSE.md
175
+ - README.md
101
176
  - Rakefile
177
+ - bin/console
178
+ - bin/setup
102
179
  - formatted_attributes.gemspec
103
180
  - lib/formatted_attributes.rb
104
- - lib/formatted_attributes/active_record.rb
105
181
  - lib/formatted_attributes/version.rb
106
- - spec/formatted_attributes_spec.rb
107
- - spec/schema.rb
108
- - spec/spec_helper.rb
109
- has_rdoc: true
110
- homepage: http://rubygems.org/gems/formatted_attributes
111
- licenses: []
112
-
113
- post_install_message:
182
+ homepage: https://github.com/fnando/formatted_attributes
183
+ licenses:
184
+ - MIT
185
+ metadata:
186
+ homepage_uri: https://github.com/fnando/formatted_attributes
187
+ bug_tracker_uri: https://github.com/fnando/formatted_attributes/issues
188
+ source_code_uri: https://github.com/fnando/formatted_attributes/tree/v0.2.0
189
+ changelog_uri: https://github.com/fnando/formatted_attributes/tree/v0.2.0/CHANGELOG.md
190
+ documentation_uri: https://github.com/fnando/formatted_attributes/tree/v0.2.0/README.md
191
+ license_uri: https://github.com/fnando/formatted_attributes/tree/v0.2.0/LICENSE.md
192
+ rubygems_mfa_required: 'true'
193
+ post_install_message:
114
194
  rdoc_options: []
115
-
116
- require_paths:
195
+ require_paths:
117
196
  - lib
118
- required_ruby_version: !ruby/object:Gem::Requirement
119
- none: false
120
- requirements:
197
+ required_ruby_version: !ruby/object:Gem::Requirement
198
+ requirements:
121
199
  - - ">="
122
- - !ruby/object:Gem::Version
123
- segments:
124
- - 0
125
- version: "0"
126
- required_rubygems_version: !ruby/object:Gem::Requirement
127
- none: false
128
- requirements:
200
+ - !ruby/object:Gem::Version
201
+ version: 2.7.0
202
+ required_rubygems_version: !ruby/object:Gem::Requirement
203
+ requirements:
129
204
  - - ">="
130
- - !ruby/object:Gem::Version
131
- segments:
132
- - 0
133
- version: "0"
205
+ - !ruby/object:Gem::Version
206
+ version: '0'
134
207
  requirements: []
135
-
136
- rubyforge_project:
137
- rubygems_version: 1.3.7
138
- signing_key:
139
- specification_version: 3
140
- summary: Add formatted methods for ActiveRecord attributes
141
- test_files:
142
- - spec/formatted_attributes_spec.rb
143
- - spec/schema.rb
144
- - spec/spec_helper.rb
208
+ rubygems_version: 3.3.3
209
+ signing_key:
210
+ specification_version: 4
211
+ summary: Add methods that format attributes from/to helper methods.
212
+ test_files: []
data/Gemfile.lock DELETED
@@ -1,79 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- formatted_attributes (0.1.0)
5
- activerecord
6
-
7
- GEM
8
- remote: http://rubygems.org/
9
- specs:
10
- abstract (1.0.0)
11
- actionpack (3.0.1)
12
- activemodel (= 3.0.1)
13
- activesupport (= 3.0.1)
14
- builder (~> 2.1.2)
15
- erubis (~> 2.6.6)
16
- i18n (~> 0.4.1)
17
- rack (~> 1.2.1)
18
- rack-mount (~> 0.6.12)
19
- rack-test (~> 0.5.4)
20
- tzinfo (~> 0.3.23)
21
- activemodel (3.0.1)
22
- activesupport (= 3.0.1)
23
- builder (~> 2.1.2)
24
- i18n (~> 0.4.1)
25
- activerecord (3.0.1)
26
- activemodel (= 3.0.1)
27
- activesupport (= 3.0.1)
28
- arel (~> 1.0.0)
29
- tzinfo (~> 0.3.23)
30
- activesupport (3.0.1)
31
- archive-tar-minitar (0.5.2)
32
- arel (1.0.1)
33
- activesupport (~> 3.0.0)
34
- builder (2.1.2)
35
- columnize (0.3.1)
36
- diff-lcs (1.1.2)
37
- erubis (2.6.6)
38
- abstract (>= 1.0.0)
39
- i18n (0.4.1)
40
- linecache19 (0.5.11)
41
- ruby_core_source (>= 0.1.4)
42
- rack (1.2.1)
43
- rack-mount (0.6.13)
44
- rack (>= 1.0.0)
45
- rack-test (0.5.6)
46
- rack (>= 1.0)
47
- rspec (2.0.1)
48
- rspec-core (~> 2.0.1)
49
- rspec-expectations (~> 2.0.1)
50
- rspec-mocks (~> 2.0.1)
51
- rspec-core (2.0.1)
52
- rspec-expectations (2.0.1)
53
- diff-lcs (>= 1.1.2)
54
- rspec-mocks (2.0.1)
55
- rspec-core (~> 2.0.1)
56
- rspec-expectations (~> 2.0.1)
57
- ruby-debug-base19 (0.11.24)
58
- columnize (>= 0.3.1)
59
- linecache19 (>= 0.5.11)
60
- ruby_core_source (>= 0.1.4)
61
- ruby-debug19 (0.11.6)
62
- columnize (>= 0.3.1)
63
- linecache19 (>= 0.5.11)
64
- ruby-debug-base19 (>= 0.11.19)
65
- ruby_core_source (0.1.4)
66
- archive-tar-minitar (>= 0.5.2)
67
- sqlite3-ruby (1.3.1)
68
- tzinfo (0.3.23)
69
-
70
- PLATFORMS
71
- ruby
72
-
73
- DEPENDENCIES
74
- actionpack
75
- activerecord
76
- formatted_attributes!
77
- rspec (>= 2.0.0)
78
- ruby-debug19
79
- sqlite3-ruby
data/README.rdoc DELETED
@@ -1,65 +0,0 @@
1
- = Formatted Attributes
2
-
3
- Sometimes you want to use a proxy attribute that will be formatted while displaying its value or receiving data from user.
4
-
5
- == Install
6
-
7
- gem install formatted_attributes
8
-
9
- == Usage
10
-
11
- A formatted attribute will require two methods: <tt>format_to_#{formatter}</tt> and <tt>format_from_#{formatter}</tt>. The <tt>format_to_*</tt> method will convert the formatted value to the original value and the <tt>format_from_*</tt> method will do the other way around, converting the original value to the formatted version.
12
-
13
- See an example on how to format prices from strings like <tt>1,23</tt> to cents like <tt>123</tt> and vice-versa.
14
-
15
- class Product < ActiveRecord::Base
16
- include ActionView::Helpers::NumberHelper
17
-
18
- formatted :price, :with => :cents
19
-
20
- private
21
- def format_to_cents(amount)
22
- _, operator, number, precision = *number.to_s.match(/^([+-])?(\d+)(?:[,.](\d+))?$/)
23
- (BigDecimal("#{operator}#{number}.#{precision.to_i}") * 100).to_i
24
- end
25
-
26
- def format_from_cents(amount)
27
- number = BigDecimal(number.to_s) / 100
28
- number_to_currency(number, :unit => "", :separator => ",", :delimiter => "")
29
- end
30
- end
31
-
32
- product = Product.new(:formatted_price => "1,23")
33
- product.price
34
- #=> 123
35
-
36
- product.price = 456
37
- product.formatted_price
38
- #=> "4,56"
39
-
40
- == Maintainer
41
-
42
- * Nando Vieira (http://nandovieira.com.br)
43
-
44
- == License
45
-
46
- (The MIT License)
47
-
48
- Permission is hereby granted, free of charge, to any person obtaining
49
- a copy of this software and associated documentation files (the
50
- 'Software'), to deal in the Software without restriction, including
51
- without limitation the rights to use, copy, modify, merge, publish,
52
- distribute, sublicense, and/or sell copies of the Software, and to
53
- permit persons to whom the Software is furnished to do so, subject to
54
- the following conditions:
55
-
56
- The above copyright notice and this permission notice shall be
57
- included in all copies or substantial portions of the Software.
58
-
59
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
60
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
61
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
62
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
63
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
64
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
65
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,39 +0,0 @@
1
- module FormattedAttributes
2
- module ActiveRecord
3
- def self.included(base)
4
- base.instance_eval do
5
- include InstanceMethods
6
- extend ClassMethods
7
- end
8
- end
9
-
10
- module ClassMethods
11
- def formatted(*args)
12
- options = args.extract_options!
13
-
14
- args.each do |attr|
15
- accessible_attributes << "formatted_#{attr}"
16
-
17
- class_eval <<-RUBY
18
- def #{attr}=(value)
19
- @formatted_#{attr} = nil
20
- write_attribute :#{attr}, value
21
- end
22
-
23
- def formatted_#{attr}
24
- @formatted_#{attr} ||= format_from_#{options[:with]}(send(:#{attr}))
25
- end
26
-
27
- def formatted_#{attr}=(value)
28
- self.send :#{attr}=, format_to_#{options[:with]}(value)
29
- @formatted_#{attr} = value
30
- end
31
- RUBY
32
- end
33
- end
34
- end
35
-
36
- module InstanceMethods
37
- end
38
- end
39
- end
@@ -1,44 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe FormattedAttributes do
4
- subject { Product.new }
5
-
6
- context "formatted methods" do
7
- it "should add getters" do
8
- subject.should respond_to(:formatted_price)
9
- subject.should respond_to(:formatted_shipping)
10
- end
11
-
12
- it "should add setters" do
13
- subject.should respond_to(:formatted_price=)
14
- subject.should respond_to(:formatted_shipping=)
15
- end
16
-
17
- it "should set initial value" do
18
- subject.price = 12300
19
- subject.formatted_price.should == "123,00"
20
- end
21
-
22
- it "should update formatted price" do
23
- subject.price = 12300
24
- subject.formatted_price.should == "123,00"
25
-
26
- subject.price = 45600
27
- subject.formatted_price.should == "456,00"
28
- end
29
-
30
- it "should set formatted value" do
31
- subject.price = 12300
32
- subject.formatted_price = "456,78"
33
- subject.formatted_price.should == "456,78"
34
- subject.price.should == 45678
35
-
36
- subject.shipping = 67800
37
- subject.formatted_shipping = "345,67"
38
- subject.formatted_shipping.should == "345,67"
39
- subject.shipping.should == 34567
40
-
41
- subject.should be_valid
42
- end
43
- end
44
- end
data/spec/schema.rb DELETED
@@ -1,5 +0,0 @@
1
- ActiveRecord::Schema.define(:version => 0) do
2
- create_table :products do |t|
3
- t.integer :price, :shipping, :default => 0, :null => false
4
- end
5
- end
data/spec/spec_helper.rb DELETED
@@ -1,25 +0,0 @@
1
- require "formatted_attributes"
2
- require "active_support/all"
3
- require "action_view/helpers/number_helper"
4
-
5
- ActiveRecord::Base.establish_connection :adapter => "sqlite3", :database => ":memory:"
6
-
7
- load File.dirname(__FILE__) + "/schema.rb"
8
-
9
- class Product < ActiveRecord::Base
10
- include ActionView::Helpers::NumberHelper
11
- formatted :price, :shipping, :with => :cents
12
-
13
- validates_numericality_of :price, :shipping, :only_integer => true
14
-
15
- private
16
- def format_to_cents(number)
17
- _, operator, number, precision = *number.to_s.match(/^([+-])?(\d+)(?:[,.](\d+))?$/)
18
- (BigDecimal("#{operator}#{number}.#{precision.to_i}") * 100).to_i
19
- end
20
-
21
- def format_from_cents(number)
22
- number = BigDecimal(number.to_s) / 100
23
- number_to_currency(number, :unit => "", :separator => ",", :delimiter => "")
24
- end
25
- end