attribute_extras 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eac09be8233da669f266305340d2f7c796cd8ab9
4
- data.tar.gz: 26f61ba42a8ecde62c87e393e9ebbe97c59fcf9e
3
+ metadata.gz: dbe2cf428824264839a52d09fe981d4212785d06
4
+ data.tar.gz: f34788ebc3efdef5db35eea0c7951e3698732d8a
5
5
  SHA512:
6
- metadata.gz: 0a2e98ec1f27972c2edaf5966582c94c423e06a2194dcf719a26938eb0e85ca5272b69ae19d96e1065f8059f7295d9de10cecdfe84198fe28ce1d98d9efeb438
7
- data.tar.gz: d49ae18115091d70f0f8fe6cb129e2b7cd45a9224673e06d9e9465bd02f8fb8413c59082230aab809014785948bcf7b9bff1bd21dea019a70e9feabdade20d21
6
+ metadata.gz: 81b22a9c17b95bbcde17c18ef0e38a329630e38cad3a054459e9b24cda64fe4ebcb11f13b75126fc40b572f2f32c2700375dc63ab819ebfba2b639f92f5eefdf
7
+ data.tar.gz: 023a5250dccab5535a615529e8dfdb3bff2940286ece963ce721272e6898c08adb6f3e445885d4c50d0b32cfe8c6fa4e7ec1ba6af7a19c532b93ef0bc553423d
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2015 Kevin Deisz
1
+ Copyright 2015 DrugDev, Inc.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ## AttributeExtras
2
2
 
3
- Use this gem for automatic behavior on attributes. It provides three class macros that can be used for managing attributes.
3
+ Use this gem for automatic behavior on attributes. It by default provides three class macros that can be used for managing attributes. You can also build your own macros that will automatically become available to you within your ActiveRecord models. By default each macro gets the options `:validator` and `:writer` and both are set to true. If you do not want the macros to validate or overwrite the attribute writers, you can pass false to those options.
4
4
 
5
5
  ### nullify_attributes
6
6
 
@@ -30,17 +30,15 @@ p.name # => 'value'
30
30
 
31
31
  ### truncate_attributes
32
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.
33
+ Causes string attribute assignment to be truncated down to the maximum allowed value for that column.
34
34
 
35
35
  ```ruby
36
36
  class Person < ActiveRecord::Base
37
- truncate_attributes :first_name
38
- truncate_attributes :last_name, whiny: true
37
+ truncate_attributes :name
39
38
  end
40
39
 
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
40
+ p = Person.new(name: 'a' * 500)
41
+ p.name # => 'a' * limit
44
42
  ```
45
43
 
46
44
  ### Inheritance
@@ -69,6 +67,29 @@ Developer.nullified_attributes.map(&:attribute) # => [:email]
69
67
  Developer.inherited_nullified_attributes.map(&:attribute) # => [:email, :name]
70
68
  ```
71
69
 
70
+ ## Internals
71
+
72
+ If you want to register your own macros, you can do so with `AttributeExtras.register_extra`. Internally `attribute_extras` does this for the three macros listed above.
73
+
74
+ ### `:nullify` Example
75
+
76
+ ```ruby
77
+ self.register_extra :nullify, ->(value, options){ value.presence },
78
+ past: :nullified,
79
+ validator: { format: { allow_nil: true, without: /\A\s*\z/ } }
80
+ ```
81
+
82
+ ### `:truncate` Example
83
+
84
+ ```ruby
85
+ self.register_extra :truncate, ->(value, options){ value.is_a?(String) ? value[0...options[:limit]] : value },
86
+ past: :truncated,
87
+ validator: ->(options){ { length: { maximum: options[:limit] } } },
88
+ options: ->(attribute){ { limit: self.columns_hash[attribute.to_s].limit } }
89
+ ```
90
+
91
+ In this case the options is needed to build a hash of metadata about the attribute in question so that the validator option can change. The options hash is also passed in to the `truncate_attribute_extra` method so that you have access to that metadata.
92
+
72
93
  ## Additional information
73
94
 
74
95
  ### Contributing
@@ -1,44 +1,8 @@
1
1
  module AttributeExtras
2
2
  module BaseExtensions
3
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
4
  # overrides the writer to truncate if that value is blank
41
- def truncate_attributes(*attributes, whiny: false)
5
+ def truncate_attributes(*attributes, validator: false, writer: true)
42
6
  string_columns = self.columns.select { |column| column.type == :string && !column.limit.nil? }.map(&:name)
43
7
  if self.table_exists? and (non_attributes = attributes.map(&:to_s) - string_columns).any?
44
8
  raise ArgumentError, <<-MSG.squish
@@ -53,15 +17,17 @@ module AttributeExtras
53
17
  attributes.each do |attribute|
54
18
  limit = self.columns_hash[attribute.to_s].limit
55
19
 
56
- if whiny
20
+ if validator
57
21
  validates attribute, length: { maximum: limit }
58
- @truncated_attributes << Modifier.new(attribute, limit: limit)
59
- else
22
+ end
23
+
24
+ if writer
60
25
  define_method("#{attribute}=") do |value|
61
- write_attribute(attribute, value.is_a?(String) ? value[0...limit] : value)
26
+ write_attribute(attribute, ::AttributeExtras::TruncateAttributes::FUNCTION[value, limit: limit])
62
27
  end
63
- @truncated_attributes << Modifier.new(attribute)
64
28
  end
29
+
30
+ truncated_attributes << Modifier.new(attribute, limit: limit)
65
31
  end
66
32
  end
67
33
 
@@ -0,0 +1,78 @@
1
+ module AttributeExtras
2
+ class ExtraBuilder
3
+
4
+ # store the given options
5
+ def initialize(verb, past, function, validator, options)
6
+ @verb = verb
7
+ @past = past
8
+ @function = function
9
+ @validator = validator
10
+ @options = options
11
+ end
12
+
13
+ # build the extra
14
+ def build
15
+ concern = Module.new
16
+ concern.module_eval(concern_definition)
17
+ concern::ClassMethods.module_eval(&utilities_definition)
18
+ concern
19
+ end
20
+
21
+ private
22
+
23
+ # the module definition for the concern
24
+ def concern_definition
25
+ <<-RUBY
26
+ extend ActiveSupport::Concern
27
+
28
+ module ClassMethods
29
+ def inherited_#{@past}_attributes
30
+ @inherited_#{@past}_attributes ||= begin
31
+ modifiers = []
32
+ self.ancestors.each do |ancestor|
33
+ break if ancestor == ActiveRecord::Base
34
+ if ancestor.respond_to?(:#{@past}_attributes)
35
+ modifiers += ancestor.#{@past}_attributes
36
+ end
37
+ end
38
+ modifiers
39
+ end
40
+ end
41
+
42
+ def #{@past}_attributes
43
+ @#{@past}_attributes ||= []
44
+ end
45
+ end
46
+
47
+ def #{@verb}_attributes
48
+ set_#{@past}_attributes
49
+ self.changed? ? self.save : true
50
+ end
51
+
52
+ def #{@verb}_attributes!
53
+ set_#{@past}_attributes
54
+ self.changed? ? self.save : true
55
+ end
56
+
57
+ private
58
+
59
+ def set_#{@past}_attributes
60
+ self.class.inherited_#{@past}_attributes.each do |modifier|
61
+ attribute = modifier.attribute
62
+ self.send(:\"\#{attribute}=\", self.class.#{@verb}_attribute_extra(self.send(attribute), modifier.options))
63
+ end
64
+ end
65
+ RUBY
66
+ end
67
+
68
+ # the module definition for the utilities
69
+ def utilities_definition
70
+ verb, function, validator, options = @verb, @function, @validator, @options
71
+ proc do
72
+ define_method(:"#{verb}_attribute_extra", function)
73
+ define_method(:"#{verb}_validator_for", validator)
74
+ define_method(:"#{verb}_options_for", options)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,49 @@
1
+ module AttributeExtras
2
+ class HookBuilder
3
+
4
+ # store the given options
5
+ def initialize(verb, past)
6
+ @verb = verb
7
+ @past = past
8
+ end
9
+
10
+ # build the hook
11
+ def build
12
+ hook = Module.new
13
+ hook.module_eval(module_definition)
14
+ hook
15
+ end
16
+
17
+ private
18
+
19
+ # the module definition for the extra
20
+ def module_definition
21
+ <<-RUBY
22
+ def #{@verb}_attributes(*attributes, validator: true, writer: true)
23
+ if self.table_exists? && (non_attributes = attributes.map(&:to_s) - self.column_names).any?
24
+ raise ArgumentError, "Invalid attributes passed to #{@verb}_attributes: \#{non_attributes.join(', ')}"
25
+ end
26
+
27
+ include ::AttributeExtras::#{@verb.capitalize}Attributes
28
+
29
+ attributes.each do |attribute|
30
+ options = self.#{@verb}_options_for(attribute)
31
+ modifier = Modifier.new(attribute, options)
32
+
33
+ if validator
34
+ validates attribute, self.#{@verb}_validator_for(modifier.options)
35
+ end
36
+
37
+ if writer
38
+ define_method("\#{attribute}=") do |value|
39
+ write_attribute(attribute, self.class.#{@verb}_attribute_extra(value, modifier.options))
40
+ end
41
+ end
42
+
43
+ #{@past}_attributes << modifier
44
+ end
45
+ end
46
+ RUBY
47
+ end
48
+ end
49
+ end
@@ -1,3 +1,3 @@
1
1
  module AttributeExtras
2
- VERSION = "0.0.1"
2
+ VERSION = '0.1.0'
3
3
  end
@@ -1,8 +1,39 @@
1
1
  require 'attribute_extras/base_extensions'
2
+ require 'attribute_extras/extra_builder'
3
+ require 'attribute_extras/hook_builder'
4
+ require 'attribute_extras/modifier'
2
5
 
3
6
  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'
7
+
8
+ # the registered extras
9
+ mattr_accessor :extras
10
+ self.extras = []
11
+
12
+ # register the extra and build the functions
13
+ def self.register_extra(verb, function, past:, validator:, options: nil)
14
+ past ||= verb
15
+ compiled_validator = validator.is_a?(Proc) ? validator : ->(options){ validator }
16
+ options ||= ->(attribute){ {} }
17
+
18
+ extra = ExtraBuilder.new(verb, past, function, compiled_validator, options).build
19
+ hook = HookBuilder.new(verb, past).build
20
+
21
+ self.const_set(:"#{verb.capitalize}Attributes", extra)
22
+ self.extras << extra
23
+ ActiveRecord::Base.extend(hook)
24
+ end
25
+
26
+ self.register_extra :nullify, ->(value, options){ value.presence },
27
+ past: :nullified,
28
+ validator: { format: { allow_nil: true, without: /\A\s*\z/ } }
29
+
30
+ self.register_extra :strip, ->(value, options){ value.is_a?(String) ? value.strip : value },
31
+ past: :stripped,
32
+ validator: { format: { without: /\A\s+|\s+\z/ } }
33
+
34
+ self.register_extra :truncate, ->(value, options){ value.is_a?(String) ? value[0...options[:limit]] : value },
35
+ past: :truncated,
36
+ validator: ->(options){ { length: { maximum: options[:limit] } } },
37
+ options: ->(attribute){ { limit: self.columns_hash[attribute.to_s].limit } }
38
+
8
39
  end
@@ -12,7 +12,6 @@ class BaseExtensionsTest < ActiveSupport::TestCase
12
12
  def test_nullify_attributes_success
13
13
  klass = address_class(:nullify_attributes, :first_line, :second_line)
14
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
15
  end
17
16
 
18
17
  def test_strip_attributes_failure
@@ -25,7 +24,6 @@ class BaseExtensionsTest < ActiveSupport::TestCase
25
24
  def test_strip_attributes_success
26
25
  klass = address_class(:strip_attributes, :first_line, :second_line)
27
26
  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
27
  end
30
28
 
31
29
  def test_truncate_attributes_failure
@@ -38,16 +36,6 @@ class BaseExtensionsTest < ActiveSupport::TestCase
38
36
  def test_truncate_attributes_success
39
37
  klass = address_class(:truncate_attributes, :first_line, :second_line)
40
38
  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
39
  end
52
40
 
53
41
  private
@@ -1,24 +1,14 @@
1
1
  require 'test_helper'
2
2
 
3
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
4
  def test_nullify_attributes
17
5
  person = Person.new
18
6
  person.set_blank_attributes
19
7
 
20
8
  assert person.nullify_attributes
21
- assert_nil person.nullified_name
9
+ person_attributes.each do |attribute|
10
+ assert_nil person.send(attribute)
11
+ end
22
12
  end
23
13
 
24
14
  def test_nullify_attributes!
@@ -26,7 +16,9 @@ class NullifyAttributesTest < ActiveSupport::TestCase
26
16
  person.set_blank_attributes
27
17
 
28
18
  assert person.nullify_attributes!
29
- assert_nil person.nullified_name
19
+ person_attributes.each do |attribute|
20
+ assert_nil person.send(attribute)
21
+ end
30
22
  end
31
23
 
32
24
  def test_nullified_attributes_inheritance
@@ -34,24 +26,32 @@ class NullifyAttributesTest < ActiveSupport::TestCase
34
26
  architect.set_blank_attributes
35
27
 
36
28
  assert architect.nullify_attributes
37
- assert_nil architect.nullified_name
38
- assert_nil architect.other_nullified_name
29
+ architect_attributes.each do |attribute|
30
+ assert_nil architect.send(attribute)
31
+ end
39
32
  end
40
33
 
41
34
  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]
35
+ assert_equal person_attributes, Person.nullified_attributes.map(&:attribute)
36
+ assert_empty Developer.nullified_attributes.map(&:attribute)
37
+ assert_equal [:architect_nullified], Architect.nullified_attributes.map(&:attribute)
47
38
  end
48
39
 
49
40
  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]
41
+ assert_equal person_attributes, Person.inherited_nullified_attributes.map(&:attribute)
42
+ assert_equal person_attributes, Developer.inherited_nullified_attributes.map(&:attribute)
43
+ assert_equal architect_attributes, Architect.inherited_nullified_attributes.map(&:attribute)
56
44
  end
45
+
46
+ private
47
+
48
+ # a list of the attributes that are nullified on the architect class
49
+ def architect_attributes
50
+ @architect_attributes ||= ([:architect_nullified] + person_attributes)
51
+ end
52
+
53
+ # a list of the attributes that are nullified on the person class
54
+ def person_attributes
55
+ @person_attributes ||= [:person_nullified_one, :person_nullified_two, :person_nullified_three, :person_nullified_four]
56
+ end
57
57
  end
@@ -1,24 +1,14 @@
1
1
  require 'test_helper'
2
2
 
3
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
4
  def test_strip_attributes
17
5
  person = Person.new
18
6
  person.set_padded_attributes
19
7
 
20
8
  assert person.strip_attributes
21
- assert_equal 'test value', person.stripped_name
9
+ person_attributes.each do |attribute|
10
+ assert_equal Person.stripped_value, person.send(attribute)
11
+ end
22
12
  end
23
13
 
24
14
  def test_strip_attributes!
@@ -26,7 +16,9 @@ class StripAttributesTest < ActiveSupport::TestCase
26
16
  person.set_padded_attributes
27
17
 
28
18
  assert person.strip_attributes!
29
- assert_equal 'test value', person.stripped_name
19
+ person_attributes.each do |attribute|
20
+ assert_equal Person.stripped_value, person.send(attribute)
21
+ end
30
22
  end
31
23
 
32
24
  def test_stripped_attributes_inheritance
@@ -34,24 +26,32 @@ class StripAttributesTest < ActiveSupport::TestCase
34
26
  architect.set_padded_attributes
35
27
 
36
28
  assert architect.strip_attributes
37
- assert_equal 'test value', architect.stripped_name
38
- assert_equal 'test value', architect.other_stripped_name
29
+ architect_attributes.each do |attribute|
30
+ assert_equal Architect.stripped_value, architect.send(attribute)
31
+ end
39
32
  end
40
33
 
41
34
  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]
35
+ assert_equal person_attributes, Person.stripped_attributes.map(&:attribute)
36
+ assert_empty Developer.stripped_attributes.map(&:attribute)
37
+ assert_equal [:architect_stripped], Architect.stripped_attributes.map(&:attribute)
47
38
  end
48
39
 
49
40
  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]
41
+ assert_equal person_attributes, Person.inherited_stripped_attributes.map(&:attribute)
42
+ assert_equal person_attributes, Developer.inherited_stripped_attributes.map(&:attribute)
43
+ assert_equal architect_attributes, Architect.inherited_stripped_attributes.map(&:attribute)
56
44
  end
45
+
46
+ private
47
+
48
+ # a list of the attributes that are stripped on the architect class
49
+ def architect_attributes
50
+ @architect_attributes ||= ([:architect_stripped] + person_attributes)
51
+ end
52
+
53
+ # a list of the attributes that are stripped on the person class
54
+ def person_attributes
55
+ @person_attributes ||= [:person_stripped_one, :person_stripped_two, :person_stripped_three, :person_stripped_four]
56
+ end
57
57
  end
data/test/test_classes.rb CHANGED
@@ -1,16 +1,15 @@
1
1
  COLUMN_LIMIT = 255
2
+ NUMBERS = %w[one two three four]
2
3
 
3
4
  ActiveRecord::Schema.define do
4
5
  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
6
+ %w[nullified stripped truncated].each do |prefix|
7
+ options = (prefix == 'truncated') ? { limit: COLUMN_LIMIT } : {}
8
+ NUMBERS.each do |number|
9
+ t.string "person_#{prefix}_#{number}", options
10
+ end
11
+ t.string "architect_#{prefix}", options
12
+ end
14
13
  end
15
14
 
16
15
  create_table :addresses, force: true do |t|
@@ -20,25 +19,32 @@ ActiveRecord::Schema.define do
20
19
  end
21
20
 
22
21
  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
22
+
23
+ { nullified: :nullify_attributes, stripped: :strip_attributes, truncated: :truncate_attributes }.each do |prefix, macro|
24
+ NUMBERS.each_with_index do |number, index|
25
+ send(macro, "person_#{prefix}_#{number}".to_sym, validator: (index / 2).even?, writer: (index % 2))
26
+ end
27
+ end
27
28
 
28
29
  def set_blank_attributes
29
- write_attribute(:nullified_name, ' ')
30
- save
30
+ NUMBERS.each do |number|
31
+ write_attribute("person_nullified_#{number}", ' ')
32
+ end
33
+ save(validate: false)
31
34
  end
32
35
 
33
36
  def set_long_attributes
34
- write_attribute(:truncated_name, self.class.long_value)
35
- write_attribute(:truncated_whiny_name, self.class.long_value)
37
+ NUMBERS.each do |number|
38
+ write_attribute("person_truncated_#{number}", self.class.long_value)
39
+ end
36
40
  save(validate: false)
37
41
  end
38
42
 
39
43
  def set_padded_attributes
40
- write_attribute(:stripped_name, ' test value ')
41
- save
44
+ NUMBERS.each do |number|
45
+ write_attribute("person_stripped_#{number}", ' test value ')
46
+ end
47
+ save(validate: false)
42
48
  end
43
49
 
44
50
  class << self
@@ -46,6 +52,10 @@ class Person < ActiveRecord::Base
46
52
  @short_value ||= ('a' * COLUMN_LIMIT)
47
53
  end
48
54
 
55
+ def stripped_value
56
+ @stripped_value ||= 'test value'
57
+ end
58
+
49
59
  def long_value
50
60
  @long_value ||= ('a' * 500)
51
61
  end
@@ -55,26 +65,22 @@ end
55
65
  class Developer < Person; end
56
66
 
57
67
  class Architect < Developer
58
- nullify_attributes :other_nullified_name
59
- strip_attributes :other_stripped_name
60
- truncate_attributes :other_truncated_name
68
+ nullify_attributes :architect_nullified
69
+ strip_attributes :architect_stripped
70
+ truncate_attributes :architect_truncated
61
71
 
62
72
  def set_blank_attributes
63
- write_attribute(:nullified_name, ' ')
64
- write_attribute(:other_nullified_name, ' ')
65
- save
73
+ write_attribute(:architect_nullified, ' ')
74
+ super
66
75
  end
67
76
 
68
77
  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
78
+ write_attribute(:architect_truncated, self.class.long_value)
79
+ super
73
80
  end
74
81
 
75
82
  def set_padded_attributes
76
- write_attribute(:stripped_name, ' test value ')
77
- write_attribute(:other_stripped_name, ' test value ')
78
- save
83
+ write_attribute(:architect_stripped, ' test value ')
84
+ super
79
85
  end
80
86
  end
@@ -1,34 +1,14 @@
1
1
  require 'test_helper'
2
2
 
3
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
4
  def test_truncate_attributes
26
5
  person = Person.new
27
6
  person.set_long_attributes
28
7
 
29
8
  assert person.truncate_attributes
30
- assert_equal Person.short_value, person.truncated_name
31
- assert_equal Person.short_value, person.truncated_whiny_name
9
+ person_attributes.each do |attribute|
10
+ assert_equal Person.short_value, person.send(attribute)
11
+ end
32
12
  end
33
13
 
34
14
  def test_truncate_attributes!
@@ -36,8 +16,9 @@ class TruncateAttributesTest < ActiveSupport::TestCase
36
16
  person.set_long_attributes
37
17
 
38
18
  assert person.truncate_attributes!
39
- assert_equal Person.short_value, person.truncated_name
40
- assert_equal Person.short_value, person.truncated_whiny_name
19
+ person_attributes.each do |attribute|
20
+ assert_equal Person.short_value, person.send(attribute)
21
+ end
41
22
  end
42
23
 
43
24
  def test_truncated_attributes_inheritance
@@ -45,25 +26,32 @@ class TruncateAttributesTest < ActiveSupport::TestCase
45
26
  architect.set_long_attributes
46
27
 
47
28
  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
29
+ architect_attributes.each do |attribute|
30
+ assert_equal Architect.short_value, architect.send(attribute)
31
+ end
51
32
  end
52
33
 
53
34
  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]
35
+ assert_equal person_attributes, Person.truncated_attributes.map(&:attribute)
36
+ assert_empty Developer.truncated_attributes.map(&:attribute)
37
+ assert_equal [:architect_truncated], Architect.truncated_attributes.map(&:attribute)
59
38
  end
60
39
 
61
40
  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]
41
+ assert_equal person_attributes, Person.inherited_truncated_attributes.map(&:attribute)
42
+ assert_equal person_attributes, Developer.inherited_truncated_attributes.map(&:attribute)
43
+ assert_equal architect_attributes, Architect.inherited_truncated_attributes.map(&:attribute)
68
44
  end
45
+
46
+ private
47
+
48
+ # a list of the attributes that are truncated on the architect class
49
+ def architect_attributes
50
+ @architect_attributes ||= ([:architect_truncated] + person_attributes)
51
+ end
52
+
53
+ # a list of the attributes that are truncated on the person class
54
+ def person_attributes
55
+ @person_attributes ||= [:person_truncated_one, :person_truncated_two, :person_truncated_three, :person_truncated_four]
56
+ end
69
57
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attribute_extras
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Deisz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-03 00:00:00.000000000 Z
11
+ date: 2015-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -38,10 +38,9 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- description: Overrides writers methods on ActiveRecord classes to allow for different
42
- behavior such as nullifying, stripping, and truncating.
41
+ description: Builds macros to automatically manipulate your models' attributes.
43
42
  email:
44
- - kevin.deisz@gmail.com
43
+ - info@trialnetworks.com
45
44
  executables: []
46
45
  extensions: []
47
46
  extra_rdoc_files: []
@@ -51,10 +50,9 @@ files:
51
50
  - Rakefile
52
51
  - lib/attribute_extras.rb
53
52
  - lib/attribute_extras/base_extensions.rb
53
+ - lib/attribute_extras/extra_builder.rb
54
+ - lib/attribute_extras/hook_builder.rb
54
55
  - 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
56
  - lib/attribute_extras/version.rb
59
57
  - test/base_extensions_test.rb
60
58
  - test/modifier_test.rb
@@ -63,7 +61,7 @@ files:
63
61
  - test/test_classes.rb
64
62
  - test/test_helper.rb
65
63
  - test/truncate_attributes_test.rb
66
- homepage: https://github.com/kddeisz/attribute_extras
64
+ homepage: https://github.com/drugdev/attribute_extras
67
65
  licenses:
68
66
  - MIT
69
67
  metadata: {}
@@ -1,49 +0,0 @@
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
@@ -1,49 +0,0 @@
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
@@ -1,53 +0,0 @@
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