attribute_extras 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +80 -0
- data/Rakefile +34 -0
- data/lib/attribute_extras.rb +8 -0
- data/lib/attribute_extras/base_extensions.rb +71 -0
- data/lib/attribute_extras/modifier.rb +14 -0
- data/lib/attribute_extras/nullify_attributes.rb +49 -0
- data/lib/attribute_extras/strip_attributes.rb +49 -0
- data/lib/attribute_extras/truncate_attributes.rb +53 -0
- data/lib/attribute_extras/version.rb +3 -0
- data/test/base_extensions_test.rb +63 -0
- data/test/modifier_test.rb +9 -0
- data/test/nullify_attributes_test.rb +57 -0
- data/test/strip_attributes_test.rb +57 -0
- data/test/test_classes.rb +80 -0
- data/test/test_helper.rb +25 -0
- data/test/truncate_attributes_test.rb +69 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: eac09be8233da669f266305340d2f7c796cd8ab9
|
4
|
+
data.tar.gz: 26f61ba42a8ecde62c87e393e9ebbe97c59fcf9e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0a2e98ec1f27972c2edaf5966582c94c423e06a2194dcf719a26938eb0e85ca5272b69ae19d96e1065f8059f7295d9de10cecdfe84198fe28ce1d98d9efeb438
|
7
|
+
data.tar.gz: d49ae18115091d70f0f8fe6cb129e2b7cd45a9224673e06d9e9465bd02f8fb8413c59082230aab809014785948bcf7b9bff1bd21dea019a70e9feabdade20d21
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2015 Kevin Deisz
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
## AttributeExtras
|
2
|
+
|
3
|
+
Use this gem for automatic behavior on attributes. It provides three class macros that can be used for managing attributes.
|
4
|
+
|
5
|
+
### nullify_attributes
|
6
|
+
|
7
|
+
Causes attribute assignment to check for presence of the given value, and set the value accordingly.
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
class Person < ActiveRecord::Base
|
11
|
+
nullify_attributes :name
|
12
|
+
end
|
13
|
+
|
14
|
+
p = Person.new(name: ' ')
|
15
|
+
p.name # => nil
|
16
|
+
```
|
17
|
+
|
18
|
+
### strip_attributes
|
19
|
+
|
20
|
+
Causes string attribute assignment to strip the given value, and set the value accordingly.
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
class Person < ActiveRecord::Base
|
24
|
+
strip_attributes :name
|
25
|
+
end
|
26
|
+
|
27
|
+
p = Person.new(name: ' value ')
|
28
|
+
p.name # => 'value'
|
29
|
+
```
|
30
|
+
|
31
|
+
### truncate_attributes
|
32
|
+
|
33
|
+
Causes string attribute assignment to be truncated down to the maximum allowed value for that column. If `whiny` is set to true, instead adds a length validator on that attribute to cause it to error if saved.
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
class Person < ActiveRecord::Base
|
37
|
+
truncate_attributes :first_name
|
38
|
+
truncate_attributes :last_name, whiny: true
|
39
|
+
end
|
40
|
+
|
41
|
+
p = Person.new(first_name: 'a' * 500, last_name: 'a' * 500)
|
42
|
+
p.first_name # => 'a' * limit
|
43
|
+
p.save! # => ActiveRecord::RecordInvalid: Validation failed
|
44
|
+
```
|
45
|
+
|
46
|
+
### Inheritance
|
47
|
+
|
48
|
+
By default, attributes that you manipulate with any of the above macros will be inherited into the subclasses.
|
49
|
+
|
50
|
+
### Other methods
|
51
|
+
|
52
|
+
For migrating values to the correct format specified, there are two methods for each macro that will enforce the format. For example, for the `nullify_attributes` macro there is the `nullify_attributes` instance method and the `nullify_attributes!` instance method. Both will set the correct values and then call their respective `save`.
|
53
|
+
|
54
|
+
For introspection, there are two methods for each macro supplied. For example, for the `nullify_attributes` macro there is the `nullified_attributes` method and the `inherited_nullified_attributes` method. Examples below:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
class Person < ActiveRecord::Base
|
58
|
+
nullify_attributes :name
|
59
|
+
end
|
60
|
+
|
61
|
+
class Developer < Person
|
62
|
+
nullify_attributes :email
|
63
|
+
end
|
64
|
+
|
65
|
+
Person.nullified_attributes.map(&:attribute) # => [:name]
|
66
|
+
Person.inherited_nullified_attributes.map(&:attribute) # => [:name]
|
67
|
+
|
68
|
+
Developer.nullified_attributes.map(&:attribute) # => [:email]
|
69
|
+
Developer.inherited_nullified_attributes.map(&:attribute) # => [:email, :name]
|
70
|
+
```
|
71
|
+
|
72
|
+
## Additional information
|
73
|
+
|
74
|
+
### Contributing
|
75
|
+
|
76
|
+
Contributions welcome! Please submit a pull request with tests.
|
77
|
+
|
78
|
+
### Licence
|
79
|
+
|
80
|
+
MIT Licence.
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'AttributeExtras'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
Bundler::GemHelper.install_tasks
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'lib'
|
28
|
+
t.libs << 'test'
|
29
|
+
t.pattern = 'test/**/*_test.rb'
|
30
|
+
t.verbose = false
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
task default: :test
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'attribute_extras/base_extensions'
|
2
|
+
|
3
|
+
module AttributeExtras
|
4
|
+
autoload :Modifier, 'attribute_extras/modifier'
|
5
|
+
autoload :NullifyAttributes, 'attribute_extras/nullify_attributes'
|
6
|
+
autoload :StripAttributes, 'attribute_extras/strip_attributes'
|
7
|
+
autoload :TruncateAttributes, 'attribute_extras/truncate_attributes'
|
8
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module AttributeExtras
|
2
|
+
module BaseExtensions
|
3
|
+
|
4
|
+
# overrides the writer to set to nil if that value is blank
|
5
|
+
def nullify_attributes(*attributes)
|
6
|
+
if self.table_exists? and (non_attributes = attributes.map(&:to_s) - self.column_names).any?
|
7
|
+
raise ArgumentError, "Invalid attributes passed to nullify_attributes: #{non_attributes.join(', ')}"
|
8
|
+
end
|
9
|
+
|
10
|
+
include ::AttributeExtras::NullifyAttributes
|
11
|
+
|
12
|
+
attributes.each do |attribute|
|
13
|
+
define_method("#{attribute}=") do |value|
|
14
|
+
write_attribute(attribute, value.presence)
|
15
|
+
end
|
16
|
+
nullified_attributes << Modifier.new(attribute)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# overrides the writer to strip the value
|
21
|
+
def strip_attributes(*attributes)
|
22
|
+
string_columns = self.columns.select { |column| column.type == :string }.map(&:name)
|
23
|
+
if self.table_exists? and (non_attributes = attributes.map(&:to_s) - string_columns).any?
|
24
|
+
raise ArgumentError, <<-MSG.squish
|
25
|
+
Invalid attributes passed to strip_attributes: #{non_attributes.join(', ')};
|
26
|
+
attributes must be string columns
|
27
|
+
MSG
|
28
|
+
end
|
29
|
+
|
30
|
+
include ::AttributeExtras::StripAttributes
|
31
|
+
|
32
|
+
attributes.each do |attribute|
|
33
|
+
define_method("#{attribute}=") do |value|
|
34
|
+
write_attribute(attribute, value.is_a?(String) ? value.strip : value)
|
35
|
+
end
|
36
|
+
stripped_attributes << Modifier.new(attribute)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# overrides the writer to truncate if that value is blank
|
41
|
+
def truncate_attributes(*attributes, whiny: false)
|
42
|
+
string_columns = self.columns.select { |column| column.type == :string && !column.limit.nil? }.map(&:name)
|
43
|
+
if self.table_exists? and (non_attributes = attributes.map(&:to_s) - string_columns).any?
|
44
|
+
raise ArgumentError, <<-MSG.squish
|
45
|
+
Invalid attributes passed to truncate_attributes: #{non_attributes.join(', ')};
|
46
|
+
attributes must be string columns that have a set limit
|
47
|
+
MSG
|
48
|
+
end
|
49
|
+
|
50
|
+
include ::AttributeExtras::TruncateAttributes
|
51
|
+
|
52
|
+
truncated_attributes
|
53
|
+
attributes.each do |attribute|
|
54
|
+
limit = self.columns_hash[attribute.to_s].limit
|
55
|
+
|
56
|
+
if whiny
|
57
|
+
validates attribute, length: { maximum: limit }
|
58
|
+
@truncated_attributes << Modifier.new(attribute, limit: limit)
|
59
|
+
else
|
60
|
+
define_method("#{attribute}=") do |value|
|
61
|
+
write_attribute(attribute, value.is_a?(String) ? value[0...limit] : value)
|
62
|
+
end
|
63
|
+
@truncated_attributes << Modifier.new(attribute)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
ActiveRecord::Base.extend AttributeExtras::BaseExtensions
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module AttributeExtras
|
2
|
+
module NullifyAttributes
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
# inherited and current nullified attributes
|
8
|
+
def inherited_nullified_attributes
|
9
|
+
@inherited_nullified_attributes ||= begin
|
10
|
+
modifiers = []
|
11
|
+
self.ancestors.each_with_object([]) do |ancestor|
|
12
|
+
break if ancestor == ActiveRecord::Base
|
13
|
+
if ancestor.respond_to?(:nullified_attributes)
|
14
|
+
modifiers += ancestor.nullified_attributes
|
15
|
+
end
|
16
|
+
end
|
17
|
+
modifiers
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# the nullified attributes for this class
|
22
|
+
def nullified_attributes
|
23
|
+
@nullified_attributes ||= []
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# calls set_nullified_attributes then save
|
28
|
+
def nullify_attributes
|
29
|
+
set_nullified_attributes
|
30
|
+
self.save if self.changed?
|
31
|
+
end
|
32
|
+
|
33
|
+
# calls set_nullified_attributes then save!
|
34
|
+
def nullify_attributes!
|
35
|
+
set_nullified_attributes
|
36
|
+
self.save! if self.changed?
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# apply the nullification to each specified nullified attribute
|
42
|
+
def set_nullified_attributes
|
43
|
+
self.class.inherited_nullified_attributes.each do |modifier|
|
44
|
+
attribute = modifier.attribute
|
45
|
+
self.send("#{attribute}=", self.send(attribute))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module AttributeExtras
|
2
|
+
module StripAttributes
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
# inherited and current stripped attributes
|
8
|
+
def inherited_stripped_attributes
|
9
|
+
@inherited_stripped_attributes ||= begin
|
10
|
+
modifiers = []
|
11
|
+
self.ancestors.each_with_object([]) do |ancestor|
|
12
|
+
break if ancestor == ActiveRecord::Base
|
13
|
+
if ancestor.respond_to?(:stripped_attributes)
|
14
|
+
modifiers += ancestor.stripped_attributes
|
15
|
+
end
|
16
|
+
end
|
17
|
+
modifiers
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# the stripped attributes for this class
|
22
|
+
def stripped_attributes
|
23
|
+
@stripped_attributes ||= []
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# calls set_stripped_attributes then save
|
28
|
+
def strip_attributes
|
29
|
+
set_stripped_attributes
|
30
|
+
self.save if self.changed?
|
31
|
+
end
|
32
|
+
|
33
|
+
# calls set_stripped_attributes then save!
|
34
|
+
def strip_attributes!
|
35
|
+
set_stripped_attributes
|
36
|
+
self.save! if self.changed?
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# apply the strip to each specified stripped attribute
|
42
|
+
def set_stripped_attributes
|
43
|
+
self.class.inherited_stripped_attributes.each do |modifier|
|
44
|
+
attribute = modifier.attribute
|
45
|
+
self.send("#{attribute}=", self.send(attribute))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module AttributeExtras
|
2
|
+
module TruncateAttributes
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
# inherited and current truncated attributes
|
8
|
+
def inherited_truncated_attributes
|
9
|
+
@inherited_truncated_attributes ||= begin
|
10
|
+
modifiers = []
|
11
|
+
self.ancestors.each_with_object([]) do |ancestor|
|
12
|
+
break if ancestor == ActiveRecord::Base
|
13
|
+
if ancestor.respond_to?(:truncated_attributes)
|
14
|
+
modifiers += ancestor.truncated_attributes
|
15
|
+
end
|
16
|
+
end
|
17
|
+
modifiers
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# the truncated attributes for this class
|
22
|
+
def truncated_attributes
|
23
|
+
@truncated_attributes ||= []
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# calls set_truncated_attributes then save
|
28
|
+
def truncate_attributes
|
29
|
+
set_truncated_attributes
|
30
|
+
self.save if self.changed?
|
31
|
+
end
|
32
|
+
|
33
|
+
# calls set_truncated_attributes then save!
|
34
|
+
def truncate_attributes!
|
35
|
+
set_truncated_attributes
|
36
|
+
self.save! if self.changed?
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# apply the truncation to each specified truncated attribute
|
42
|
+
def set_truncated_attributes
|
43
|
+
self.class.inherited_truncated_attributes.each do |modifier|
|
44
|
+
attribute = modifier.attribute
|
45
|
+
if modifier.options[:limit]
|
46
|
+
self.send("#{attribute}=", self.send(attribute)[0...modifier.options[:limit]])
|
47
|
+
else
|
48
|
+
self.send("#{attribute}=", self.send(attribute))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BaseExtensionsTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
def test_nullify_attributes_failure
|
6
|
+
assert_raises ArgumentError do
|
7
|
+
klass = address_class(:nullify_attributes, :first_line, :second_line, :third_line)
|
8
|
+
assert_not klass.respond_to?(:nullified_attributes)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_nullify_attributes_success
|
13
|
+
klass = address_class(:nullify_attributes, :first_line, :second_line)
|
14
|
+
assert_equal klass.nullified_attributes.map(&:attribute), [:first_line, :second_line]
|
15
|
+
assert_includes klass.instance_method(:first_line=).source_location.first, 'attribute_extras/base_extensions'
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_strip_attributes_failure
|
19
|
+
assert_raises ArgumentError do
|
20
|
+
klass = address_class(:strip_attributes, :first_line, :second_line, :third_line)
|
21
|
+
assert_not klass.respond_to?(:stripped_attributes)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_strip_attributes_success
|
26
|
+
klass = address_class(:strip_attributes, :first_line, :second_line)
|
27
|
+
assert_equal klass.stripped_attributes.map(&:attribute), [:first_line, :second_line]
|
28
|
+
assert_includes klass.instance_method(:first_line=).source_location.first, 'attribute_extras/base_extensions'
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_truncate_attributes_failure
|
32
|
+
assert_raises ArgumentError do
|
33
|
+
klass = address_class(:truncate_attributes, :first_line, :second_line, :third_line)
|
34
|
+
assert_not klass.respond_to?(:truncated_attributes)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_truncate_attributes_success
|
39
|
+
klass = address_class(:truncate_attributes, :first_line, :second_line)
|
40
|
+
assert_equal klass.truncated_attributes.map(&:attribute), [:first_line, :second_line]
|
41
|
+
assert_includes klass.instance_method(:first_line=).source_location.first, 'attribute_extras/base_extensions'
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_truncate_attributes_success_whiny
|
45
|
+
klass = address_class(:truncate_attributes, :first_line, :second_line, whiny: true)
|
46
|
+
assert_equal klass.truncated_attributes.map(&:attribute), [:first_line, :second_line]
|
47
|
+
|
48
|
+
validator = klass.validators_on(:first_line).first
|
49
|
+
assert_kind_of ActiveModel::Validations::LengthValidator, validator
|
50
|
+
assert_equal validator.options[:maximum], COLUMN_LIMIT
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# returns a newly created address class
|
56
|
+
def address_class(macro, *arguments)
|
57
|
+
Class.new(ActiveRecord::Base) do
|
58
|
+
self.table_name = 'addresses'
|
59
|
+
send(macro, *arguments)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class NullifyAttributesTest < ActiveSupport::TestCase
|
4
|
+
def test_nullified_name=
|
5
|
+
person = Person.new
|
6
|
+
person.nullified_name = ' '
|
7
|
+
assert_nil person.nullified_name
|
8
|
+
|
9
|
+
person.nullified_name = nil
|
10
|
+
assert_nil person.nullified_name
|
11
|
+
|
12
|
+
person.nullified_name = 'test_value'
|
13
|
+
assert_equal 'test_value', person.nullified_name
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_nullify_attributes
|
17
|
+
person = Person.new
|
18
|
+
person.set_blank_attributes
|
19
|
+
|
20
|
+
assert person.nullify_attributes
|
21
|
+
assert_nil person.nullified_name
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_nullify_attributes!
|
25
|
+
person = Person.new
|
26
|
+
person.set_blank_attributes
|
27
|
+
|
28
|
+
assert person.nullify_attributes!
|
29
|
+
assert_nil person.nullified_name
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_nullified_attributes_inheritance
|
33
|
+
architect = Architect.new
|
34
|
+
architect.set_blank_attributes
|
35
|
+
|
36
|
+
assert architect.nullify_attributes
|
37
|
+
assert_nil architect.nullified_name
|
38
|
+
assert_nil architect.other_nullified_name
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_nullified_attributes
|
42
|
+
assert_equal Person.nullified_attributes.map(&:attribute),
|
43
|
+
[:nullified_name]
|
44
|
+
assert_equal Developer.nullified_attributes.map(&:attribute), []
|
45
|
+
assert_equal Architect.nullified_attributes.map(&:attribute),
|
46
|
+
[:other_nullified_name]
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_inherited_nullified_attributes
|
50
|
+
assert_equal Person.inherited_nullified_attributes.map(&:attribute),
|
51
|
+
[:nullified_name]
|
52
|
+
assert_equal Developer.inherited_nullified_attributes.map(&:attribute),
|
53
|
+
[:nullified_name]
|
54
|
+
assert_equal Architect.inherited_nullified_attributes.map(&:attribute),
|
55
|
+
[:other_nullified_name, :nullified_name]
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class StripAttributesTest < ActiveSupport::TestCase
|
4
|
+
def test_stripped_name=
|
5
|
+
person = Person.new
|
6
|
+
person.stripped_name = ' test value '
|
7
|
+
assert_equal 'test value', person.stripped_name
|
8
|
+
|
9
|
+
person.stripped_name = nil
|
10
|
+
assert_nil person.stripped_name
|
11
|
+
|
12
|
+
person.stripped_name = 'test value'
|
13
|
+
assert_equal 'test value', person.stripped_name
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_strip_attributes
|
17
|
+
person = Person.new
|
18
|
+
person.set_padded_attributes
|
19
|
+
|
20
|
+
assert person.strip_attributes
|
21
|
+
assert_equal 'test value', person.stripped_name
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_strip_attributes!
|
25
|
+
person = Person.new
|
26
|
+
person.set_padded_attributes
|
27
|
+
|
28
|
+
assert person.strip_attributes!
|
29
|
+
assert_equal 'test value', person.stripped_name
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_stripped_attributes_inheritance
|
33
|
+
architect = Architect.new
|
34
|
+
architect.set_padded_attributes
|
35
|
+
|
36
|
+
assert architect.strip_attributes
|
37
|
+
assert_equal 'test value', architect.stripped_name
|
38
|
+
assert_equal 'test value', architect.other_stripped_name
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_stripped_attributes
|
42
|
+
assert_equal Person.stripped_attributes.map(&:attribute),
|
43
|
+
[:stripped_name]
|
44
|
+
assert_equal Developer.stripped_attributes.map(&:attribute), []
|
45
|
+
assert_equal Architect.stripped_attributes.map(&:attribute),
|
46
|
+
[:other_stripped_name]
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_inherited_stripped_attributes
|
50
|
+
assert_equal Person.inherited_stripped_attributes.map(&:attribute),
|
51
|
+
[:stripped_name]
|
52
|
+
assert_equal Developer.inherited_stripped_attributes.map(&:attribute),
|
53
|
+
[:stripped_name]
|
54
|
+
assert_equal Architect.inherited_stripped_attributes.map(&:attribute),
|
55
|
+
[:other_stripped_name, :stripped_name]
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
COLUMN_LIMIT = 255
|
2
|
+
|
3
|
+
ActiveRecord::Schema.define do
|
4
|
+
create_table :people, force: true do |t|
|
5
|
+
t.string :nullified_name
|
6
|
+
t.string :other_nullified_name
|
7
|
+
|
8
|
+
t.string :stripped_name
|
9
|
+
t.string :other_stripped_name
|
10
|
+
|
11
|
+
t.string :truncated_name, limit: COLUMN_LIMIT
|
12
|
+
t.string :truncated_whiny_name, limit: COLUMN_LIMIT
|
13
|
+
t.string :other_truncated_name, limit: COLUMN_LIMIT
|
14
|
+
end
|
15
|
+
|
16
|
+
create_table :addresses, force: true do |t|
|
17
|
+
t.string :first_line, limit: COLUMN_LIMIT
|
18
|
+
t.string :second_line, limit: COLUMN_LIMIT
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Person < ActiveRecord::Base
|
23
|
+
nullify_attributes :nullified_name
|
24
|
+
strip_attributes :stripped_name
|
25
|
+
truncate_attributes :truncated_name
|
26
|
+
truncate_attributes :truncated_whiny_name, whiny: true
|
27
|
+
|
28
|
+
def set_blank_attributes
|
29
|
+
write_attribute(:nullified_name, ' ')
|
30
|
+
save
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_long_attributes
|
34
|
+
write_attribute(:truncated_name, self.class.long_value)
|
35
|
+
write_attribute(:truncated_whiny_name, self.class.long_value)
|
36
|
+
save(validate: false)
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_padded_attributes
|
40
|
+
write_attribute(:stripped_name, ' test value ')
|
41
|
+
save
|
42
|
+
end
|
43
|
+
|
44
|
+
class << self
|
45
|
+
def short_value
|
46
|
+
@short_value ||= ('a' * COLUMN_LIMIT)
|
47
|
+
end
|
48
|
+
|
49
|
+
def long_value
|
50
|
+
@long_value ||= ('a' * 500)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Developer < Person; end
|
56
|
+
|
57
|
+
class Architect < Developer
|
58
|
+
nullify_attributes :other_nullified_name
|
59
|
+
strip_attributes :other_stripped_name
|
60
|
+
truncate_attributes :other_truncated_name
|
61
|
+
|
62
|
+
def set_blank_attributes
|
63
|
+
write_attribute(:nullified_name, ' ')
|
64
|
+
write_attribute(:other_nullified_name, ' ')
|
65
|
+
save
|
66
|
+
end
|
67
|
+
|
68
|
+
def set_long_attributes
|
69
|
+
write_attribute(:truncated_name, self.class.long_value)
|
70
|
+
write_attribute(:truncated_whiny_name, self.class.long_value)
|
71
|
+
write_attribute(:other_truncated_name, self.class.long_value)
|
72
|
+
save
|
73
|
+
end
|
74
|
+
|
75
|
+
def set_padded_attributes
|
76
|
+
write_attribute(:stripped_name, ' test value ')
|
77
|
+
write_attribute(:other_stripped_name, ' test value ')
|
78
|
+
save
|
79
|
+
end
|
80
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'bundler/inline'
|
5
|
+
rescue LoadError => e
|
6
|
+
$stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
|
7
|
+
raise e
|
8
|
+
end
|
9
|
+
|
10
|
+
gemfile(true) do
|
11
|
+
source 'https://rubygems.org'
|
12
|
+
gem 'activerecord'
|
13
|
+
gem 'sqlite3'
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'active_record'
|
17
|
+
require 'minitest/autorun'
|
18
|
+
require 'logger'
|
19
|
+
require 'attribute_extras'
|
20
|
+
|
21
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
|
22
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
23
|
+
ActiveSupport.test_order = :sorted
|
24
|
+
|
25
|
+
require 'test_classes'
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TruncateAttributesTest < ActiveSupport::TestCase
|
4
|
+
def test_truncated_name=
|
5
|
+
person = Person.new
|
6
|
+
person.truncated_name = Person.long_value
|
7
|
+
assert_equal Person.short_value, person.truncated_name
|
8
|
+
|
9
|
+
person.truncated_name = nil
|
10
|
+
assert_equal nil, person.truncated_name
|
11
|
+
|
12
|
+
person.truncated_name = 'test_value'
|
13
|
+
assert_equal 'test_value', person.truncated_name
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_truncated_whiny_name_validation
|
17
|
+
person = Person.new
|
18
|
+
person.truncated_whiny_name = Person.long_value
|
19
|
+
|
20
|
+
assert_not person.save
|
21
|
+
assert_equal ["is too long (maximum is #{COLUMN_LIMIT} characters)"],
|
22
|
+
person.errors[:truncated_whiny_name]
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_truncate_attributes
|
26
|
+
person = Person.new
|
27
|
+
person.set_long_attributes
|
28
|
+
|
29
|
+
assert person.truncate_attributes
|
30
|
+
assert_equal Person.short_value, person.truncated_name
|
31
|
+
assert_equal Person.short_value, person.truncated_whiny_name
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_truncate_attributes!
|
35
|
+
person = Person.new
|
36
|
+
person.set_long_attributes
|
37
|
+
|
38
|
+
assert person.truncate_attributes!
|
39
|
+
assert_equal Person.short_value, person.truncated_name
|
40
|
+
assert_equal Person.short_value, person.truncated_whiny_name
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_truncated_attributes_inheritance
|
44
|
+
architect = Architect.new
|
45
|
+
architect.set_long_attributes
|
46
|
+
|
47
|
+
assert architect.truncate_attributes
|
48
|
+
assert_equal Person.short_value, architect.truncated_name
|
49
|
+
assert_equal Person.short_value, architect.truncated_whiny_name
|
50
|
+
assert_equal Person.short_value, architect.other_truncated_name
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_truncated_attributes
|
54
|
+
assert_equal Person.truncated_attributes.map(&:attribute),
|
55
|
+
[:truncated_name, :truncated_whiny_name]
|
56
|
+
assert_equal Developer.truncated_attributes.map(&:attribute), []
|
57
|
+
assert_equal Architect.truncated_attributes.map(&:attribute),
|
58
|
+
[:other_truncated_name]
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_inherited_truncated_attributes
|
62
|
+
assert_equal Person.inherited_truncated_attributes.map(&:attribute),
|
63
|
+
[:truncated_name, :truncated_whiny_name]
|
64
|
+
assert_equal Developer.inherited_truncated_attributes.map(&:attribute),
|
65
|
+
[:truncated_name, :truncated_whiny_name]
|
66
|
+
assert_equal Architect.inherited_truncated_attributes.map(&:attribute),
|
67
|
+
[:other_truncated_name, :truncated_name, :truncated_whiny_name]
|
68
|
+
end
|
69
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: attribute_extras
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kevin Deisz
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Overrides writers methods on ActiveRecord classes to allow for different
|
42
|
+
behavior such as nullifying, stripping, and truncating.
|
43
|
+
email:
|
44
|
+
- kevin.deisz@gmail.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- MIT-LICENSE
|
50
|
+
- README.md
|
51
|
+
- Rakefile
|
52
|
+
- lib/attribute_extras.rb
|
53
|
+
- lib/attribute_extras/base_extensions.rb
|
54
|
+
- lib/attribute_extras/modifier.rb
|
55
|
+
- lib/attribute_extras/nullify_attributes.rb
|
56
|
+
- lib/attribute_extras/strip_attributes.rb
|
57
|
+
- lib/attribute_extras/truncate_attributes.rb
|
58
|
+
- lib/attribute_extras/version.rb
|
59
|
+
- test/base_extensions_test.rb
|
60
|
+
- test/modifier_test.rb
|
61
|
+
- test/nullify_attributes_test.rb
|
62
|
+
- test/strip_attributes_test.rb
|
63
|
+
- test/test_classes.rb
|
64
|
+
- test/test_helper.rb
|
65
|
+
- test/truncate_attributes_test.rb
|
66
|
+
homepage: https://github.com/kddeisz/attribute_extras
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
metadata: {}
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 2.4.5
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: Extra macros for auto attribute manipulation.
|
90
|
+
test_files:
|
91
|
+
- test/base_extensions_test.rb
|
92
|
+
- test/modifier_test.rb
|
93
|
+
- test/nullify_attributes_test.rb
|
94
|
+
- test/strip_attributes_test.rb
|
95
|
+
- test/test_classes.rb
|
96
|
+
- test/test_helper.rb
|
97
|
+
- test/truncate_attributes_test.rb
|