whyvalidationssuckin96 1.1.0 → 1.2.0

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/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.2.0
@@ -1,3 +1,2 @@
1
1
  module WhyValidationsSuckIn96
2
-
3
2
  end
@@ -0,0 +1,38 @@
1
+ require 'active_record/autosave_association'
2
+
3
+ module WhyValidationsSuckIn96
4
+ module ActiveRecord
5
+ module AssociationValidation
6
+
7
+ def self.included(klass_or_mod)
8
+ klass_or_mod.module_eval do
9
+ extend ClassMethods
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+ def self.extended(klass_or_mod)
15
+ (class << klass_or_mod; self; end).instance_eval do
16
+ # FIXME - alias method chain my ass
17
+ alias_method_chain :add_autosave_association_callbacks, :validation_hooks
18
+ end
19
+ end
20
+
21
+ def add_autosave_association_callbacks_with_validation_hooks(reflection)
22
+ add_autosave_association_callbacks_without_validation_hooks(reflection)
23
+ setup_validations_for_association_reflection(reflection)
24
+ end
25
+
26
+ private
27
+
28
+ def setup_validations_for_association_reflection(reflection)
29
+ return false unless reflection.options[:validate] || reflection.options[:autosave]
30
+ setup_validations { validates_associated reflection.name.to_sym, :on => :save }
31
+ end
32
+
33
+ end # ClassMethods
34
+ end # AssociationValidation
35
+ end # ActiveRecord
36
+ end # WhyValidationsSuckIn96
37
+
38
+ ActiveRecord::Base.instance_eval { include WhyValidationsSuckIn96::ActiveRecord::AssociationValidation }
@@ -0,0 +1,124 @@
1
+ require 'active_record/base'
2
+ require 'active_record/callbacks'
3
+
4
+ module WhyValidationsSuckIn96
5
+ module ActiveRecord
6
+ class << self
7
+ attr_accessor :warn_on_deprecation
8
+ end
9
+ self.warn_on_deprecation = true
10
+
11
+ RemovableInstanceMethods = %w[invalid? validate_on_create validate_on_update validate errors]
12
+ RemovableClassMethods = %w[validate validate_on_create validate_on_update validates_format_of validates_each
13
+ validates_inclusion_of validates_size_of validates_confirmation_of validates_exclusion_of
14
+ validates_uniqueness_of validates_associated validates_acceptance_of
15
+ validates_numericality_of validates_presence_of validates_length_of]
16
+
17
+ def self.included(klass_or_mod)
18
+ remove_active_record_validation_related_methods_from(klass_or_mod)
19
+ klass_or_mod.instance_eval do
20
+ include WhyValidationsSuckIn96::ValidationSupport
21
+ include WhyValidationsSuckIn96::ActiveRecord::InstanceMethods
22
+ extend WhyValidationsSuckIn96::ActiveRecord::ClassMethods
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ # FIXME - holy mother of god is this a nasty method
29
+ def self.remove_active_record_validation_related_methods_from(klass_or_mod)
30
+ method_map = {klass_or_mod => RemovableInstanceMethods, (class<<klass_or_mod;self;end) => RemovableClassMethods}
31
+ method_map.each do |context, removable_methods|
32
+ context.instance_eval do
33
+ removable_methods.each do |removable_method|
34
+ begin
35
+ remove_method removable_method
36
+ rescue => e
37
+ undef_method removable_method
38
+ end
39
+ end # removable_methods.each
40
+ end # context.instance_eval
41
+ end # method_map.each
42
+ end
43
+
44
+ module ClassMethods
45
+
46
+ # FIXME - this is a seedy hack and i blame the entire contents of active_record/autosave_association.rb
47
+ # for it being necessary.
48
+ def validate(*args)
49
+ return false unless WhyValidationsSuckIn96::ActiveRecord.warn_on_deprecation
50
+ callstack = caller
51
+ warn(<<-EOW.gsub(/^\s{10}/, ""))
52
+ This is a friendly message from WhyValidationsSuckIn96. #{self.inspect} called 'validate' which is a
53
+ deprecated method. The arguments given were:
54
+
55
+ #{args.inspect} - #{block_given? ? 'block given' : 'no block given'}
56
+
57
+ and the caller was:
58
+
59
+ #{callstack.first}
60
+
61
+ If these warnings are coming from a call to 'add_autosave_association_callbacks', do not be alarmed, as
62
+ WhyValidationsSuckIn96 has implemented its own versions of the necessary validation callbacks.
63
+
64
+ These warnings can be silenced by setting 'WhyValidationsSuckIn96::ActiveRecord.warn_on_deprecation' to false.
65
+ You will now be returned to your regularly scheduled programming.
66
+ EOW
67
+ false
68
+ end
69
+
70
+ end # ClassMethods
71
+
72
+ module InstanceMethods
73
+
74
+ def self.included(klass_or_mod)
75
+ klass_or_mod.module_eval do
76
+ alias_method :valid_without_callbacks?, :valid_with_lifecycle_checking?
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ def validations_for_current_lifecycle
83
+ validations_for_save + (new_record? ? validations_for_create : validations_for_update)
84
+ end
85
+
86
+ def valid_with_lifecycle_checking?
87
+ validations_for_current_lifecycle.collect do |validation|
88
+ validation.validates?
89
+ end.all?
90
+ end
91
+
92
+ def validations_for_update
93
+ all_validations.select do |validation|
94
+ validation.options[:on] == :update
95
+ end
96
+ end
97
+
98
+ def validations_for_create
99
+ all_validations.select do |validation|
100
+ validation.options[:on] == :create
101
+ end
102
+ end
103
+
104
+ def validations_for_save
105
+ all_validations.select do |validation|
106
+ validation.options[:on].nil? || validation.options[:on] == :save
107
+ end
108
+ end
109
+
110
+ end # InstanceMethods
111
+ end # ActiveRecord
112
+ end # WhyValidationsSuckIn96
113
+
114
+ module ActiveRecord
115
+ class RecordInvalid < ActiveRecordError
116
+ attr_reader :record
117
+ def initialize(record)
118
+ @record = record
119
+ super
120
+ end
121
+ end # RecordInvalid
122
+ end # ActiveRecord
123
+
124
+ ActiveRecord::Base.instance_eval { include WhyValidationsSuckIn96::ActiveRecord }
@@ -1,94 +1,5 @@
1
1
  require 'whyvalidationssuckin96'
2
2
  require 'active_record'
3
- require 'active_record/base'
4
- require 'active_record/callbacks'
5
- require 'whyvalidationssuckin96/rails/macros'
6
-
7
- module WhyValidationsSuckIn96
8
-
9
- module ActiveRecord
10
- RemovableInstanceMethods = %w[invalid? validate_on_create validate_on_update validate errors]
11
- RemovableClassMethods = %w[validate validate_on_create validate_on_update validates_format_of validates_each
12
- validates_inclusion_of validates_size_of validates_confirmation_of validates_exclusion_of
13
- validates_uniqueness_of validates_associated validates_acceptance_of
14
- validates_numericality_of validates_presence_of validates_length_of]
15
-
16
- def self.included(klass_or_mod)
17
- remove_active_record_validation_related_methods_from(klass_or_mod)
18
- klass_or_mod.instance_eval do
19
- include WhyValidationsSuckIn96::ValidationSupport
20
- include WhyValidationsSuckIn96::ActiveRecord::InstanceMethods
21
- end
22
- end
23
-
24
- private
25
-
26
- # FIXME - holy mother of god is this a nasty method
27
- def self.remove_active_record_validation_related_methods_from(klass_or_mod)
28
- method_map = {klass_or_mod => RemovableInstanceMethods, (class<<klass_or_mod;self;end) => RemovableClassMethods}
29
- method_map.each do |context, removable_methods|
30
- context.instance_eval do
31
- removable_methods.each do |removable_method|
32
- begin
33
- remove_method removable_method
34
- rescue => e
35
- undef_method removable_method
36
- end
37
- end # removable_methods.each
38
- end # context.instance_eval
39
- end # method_map.each
40
- end
41
-
42
- module InstanceMethods
43
-
44
- def self.included(klass_or_mod)
45
- klass_or_mod.module_eval do
46
- alias_method :valid_without_callbacks?, :valid_with_lifecycle_checking?
47
- end
48
- end
49
-
50
- private
51
-
52
- def validations_for_current_lifecycle
53
- validations_for_save + (new_record? ? validations_for_create : validations_for_update)
54
- end
55
-
56
- def valid_with_lifecycle_checking?
57
- validations_for_current_lifecycle.collect do |validation|
58
- validation.validates?
59
- end.all?
60
- end
61
-
62
- def validations_for_update
63
- all_validations.select do |validation|
64
- validation.options[:on] == :update
65
- end
66
- end
67
-
68
- def validations_for_create
69
- all_validations.select do |validation|
70
- validation.options[:on] == :create
71
- end
72
- end
73
-
74
- def validations_for_save
75
- all_validations.select do |validation|
76
- validation.options[:on].nil? || validation.options[:on] == :save
77
- end
78
- end
79
-
80
- end # InstanceMethods
81
- end # ActiveRecord
82
- end # WhyValidationsSuckIn96
83
-
84
- module ActiveRecord
85
- class RecordInvalid < ActiveRecordError
86
- attr_reader :record
87
- def initialize(record)
88
- @record = record
89
- super
90
- end
91
- end # RecordInvalid
92
- end # ActiveRecord
93
-
94
- ActiveRecord::Base.instance_eval { include WhyValidationsSuckIn96::ActiveRecord }
3
+ require 'whyvalidationssuckin96/rails/active_record/base_validation_overrides'
4
+ require 'whyvalidationssuckin96/rails/active_record/association_validation'
5
+ require 'whyvalidationssuckin96/rails/macros'
@@ -1,4 +1,5 @@
1
1
  require 'whyvalidationssuckin96/rails/active_record'
2
+ WhyValidationsSuckIn96::ActiveRecord.warn_on_deprecation = false
2
3
 
3
4
  ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
4
5
  ActiveRecord::Schema.define(:version => 1) do
@@ -11,8 +12,44 @@ ActiveRecord::Schema.define(:version => 1) do
11
12
  t.string :author
12
13
  t.string :type
13
14
  end
15
+
16
+ create_table :books do |t|
17
+ t.string :name
18
+ t.has_one :glossary
19
+ t.has_many :chapters
20
+ end
21
+
22
+ create_table :glossaries do |t|
23
+ t.belongs_to :book
24
+ end
25
+
26
+ create_table :chapters do |t|
27
+ t.string :name
28
+ t.belongs_to :book
29
+ end
30
+
31
+ create_table :genres do |t|
32
+ t.string :name
33
+ end
34
+
35
+ create_table :books_genres, :id => false do |t|
36
+ t.belongs_to :book
37
+ t.belongs_to :genre
38
+ end
14
39
  end
15
40
 
41
+ class Glossary < ActiveRecord::Base
42
+ end
43
+
44
+ class Book < ActiveRecord::Base
45
+ end
46
+
47
+ class Chapter < ActiveRecord::Base
48
+ end
49
+
50
+ class Genre < ActiveRecord::Base
51
+ end
52
+
16
53
  class MusicalWork < ActiveRecord::Base
17
54
  attr_accessor :state, :callbacks_run, :validations_run
18
55
 
@@ -0,0 +1,114 @@
1
+ require 'teststrap'
2
+ require 'rails/active_record_test_helper'
3
+
4
+ context "association validation" do
5
+ has_association_validation = lambda do |klass,assoc|
6
+ !klass.validation_collection.detect do |(validation_klass,opts)|
7
+ validation_klass == WhyValidationsSuckIn96::ValidatesAssociated && opts[:attribute] == assoc && opts[:on] == :save
8
+ end.nil?
9
+ end
10
+
11
+ context "against has_many" do
12
+ context "with :validate set to true" do
13
+ setup do
14
+ Class.new(Book) do
15
+ has_many :chapters, :validate => true
16
+ end
17
+ end
18
+
19
+ should "set up an association validation" do
20
+ has_association_validation[topic, :chapters]
21
+ end
22
+ end # with :validate set to true
23
+
24
+ context "with :validate set to false" do
25
+ setup do
26
+ Class.new(Book) do
27
+ has_many :chapters, :validate => false
28
+ end
29
+ end
30
+
31
+ should "not set up an association validation" do
32
+ has_association_validation[topic, :chapters]
33
+ end.equals(false)
34
+ end # with :validate set to false
35
+ end # against has_many
36
+
37
+ context "against has_and_belongs_to_many" do
38
+ context "with :validate set to true" do
39
+ setup do
40
+ Class.new(Genre) do
41
+ has_and_belongs_to_many :books, :validate => true
42
+ end
43
+ end
44
+
45
+ should "set up an association validation" do
46
+ has_association_validation[topic, :books]
47
+ end
48
+ end # with :validate set to true
49
+
50
+ context "with :validate set to false" do
51
+ setup do
52
+ Class.new(Genre) do
53
+ has_and_belongs_to_many :books, :validate => false
54
+ end
55
+ end
56
+
57
+ should "not set up an association validation" do
58
+ has_association_validation[topic, :books]
59
+ end.equals(false)
60
+ end # with :validate set to false
61
+ end # against has_and_belongs_to_many
62
+
63
+ context "against has_one" do
64
+ context "with :validate set to true" do
65
+ setup do
66
+ Class.new(Book) do
67
+ has_one :glossary, :validate => true
68
+ end
69
+ end
70
+
71
+ should "set up an association validation" do
72
+ has_association_validation[topic, :glossary]
73
+ end
74
+ end # with :validate set to true
75
+
76
+ context "with :validate set to false" do
77
+ setup do
78
+ Class.new(Book) do
79
+ has_one :glossary, :validate => false
80
+ end
81
+ end
82
+
83
+ should "not set up an association validation" do
84
+ has_association_validation[topic, :glossary]
85
+ end.equals(false)
86
+ end # with :validate set to false
87
+ end # against has_one
88
+
89
+ context "against belongs_to" do
90
+ context "with :validate set to true" do
91
+ setup do
92
+ Class.new(Chapter) do
93
+ belongs_to :book, :validate => true
94
+ end
95
+ end
96
+
97
+ should "set up an association validation" do
98
+ has_association_validation[topic, :book]
99
+ end
100
+ end # with :validate set to true
101
+
102
+ context "with :validate set to false" do
103
+ setup do
104
+ Class.new(Chapter) do
105
+ belongs_to :book, :validate => false
106
+ end
107
+ end
108
+
109
+ should "not set up an association validation" do
110
+ has_association_validation[topic, :book]
111
+ end.equals(false)
112
+ end # with :validate set to false
113
+ end # against belongs_to
114
+ end # association validation
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{whyvalidationssuckin96}
8
- s.version = "1.1.0"
8
+ s.version = "1.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["gabrielg", "douglasmeyer"]
@@ -81,6 +81,8 @@ Gem::Specification.new do |s|
81
81
  "lib/whyvalidationssuckin96/macros/validates_presence.rb",
82
82
  "lib/whyvalidationssuckin96/macros/validates_url.rb",
83
83
  "lib/whyvalidationssuckin96/rails/active_record.rb",
84
+ "lib/whyvalidationssuckin96/rails/active_record/association_validation.rb",
85
+ "lib/whyvalidationssuckin96/rails/active_record/base_validation_overrides.rb",
84
86
  "lib/whyvalidationssuckin96/rails/macros.rb",
85
87
  "lib/whyvalidationssuckin96/rails/macros/validates_uniqueness.rb",
86
88
  "lib/whyvalidationssuckin96/skippable_validation.rb",
@@ -98,8 +100,9 @@ Gem::Specification.new do |s|
98
100
  "test/macros/validates_numericality_test.rb",
99
101
  "test/macros/validates_presence_test.rb",
100
102
  "test/macros/validates_url_test.rb",
101
- "test/rails/active_record_test.rb",
102
103
  "test/rails/active_record_test_helper.rb",
104
+ "test/rails/association_validation_test.rb",
105
+ "test/rails/base_validation_overrides_test.rb",
103
106
  "test/rails/macros/validates_uniqueness_test.rb",
104
107
  "test/skippable_validation_test.rb",
105
108
  "test/teststrap.rb",
@@ -125,8 +128,9 @@ Gem::Specification.new do |s|
125
128
  "test/macros/validates_numericality_test.rb",
126
129
  "test/macros/validates_presence_test.rb",
127
130
  "test/macros/validates_url_test.rb",
128
- "test/rails/active_record_test.rb",
129
131
  "test/rails/active_record_test_helper.rb",
132
+ "test/rails/association_validation_test.rb",
133
+ "test/rails/base_validation_overrides_test.rb",
130
134
  "test/rails/macros/validates_uniqueness_test.rb",
131
135
  "test/skippable_validation_test.rb",
132
136
  "test/teststrap.rb",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: whyvalidationssuckin96
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - gabrielg
@@ -117,6 +117,8 @@ files:
117
117
  - lib/whyvalidationssuckin96/macros/validates_presence.rb
118
118
  - lib/whyvalidationssuckin96/macros/validates_url.rb
119
119
  - lib/whyvalidationssuckin96/rails/active_record.rb
120
+ - lib/whyvalidationssuckin96/rails/active_record/association_validation.rb
121
+ - lib/whyvalidationssuckin96/rails/active_record/base_validation_overrides.rb
120
122
  - lib/whyvalidationssuckin96/rails/macros.rb
121
123
  - lib/whyvalidationssuckin96/rails/macros/validates_uniqueness.rb
122
124
  - lib/whyvalidationssuckin96/skippable_validation.rb
@@ -134,8 +136,9 @@ files:
134
136
  - test/macros/validates_numericality_test.rb
135
137
  - test/macros/validates_presence_test.rb
136
138
  - test/macros/validates_url_test.rb
137
- - test/rails/active_record_test.rb
138
139
  - test/rails/active_record_test_helper.rb
140
+ - test/rails/association_validation_test.rb
141
+ - test/rails/base_validation_overrides_test.rb
139
142
  - test/rails/macros/validates_uniqueness_test.rb
140
143
  - test/skippable_validation_test.rb
141
144
  - test/teststrap.rb
@@ -183,8 +186,9 @@ test_files:
183
186
  - test/macros/validates_numericality_test.rb
184
187
  - test/macros/validates_presence_test.rb
185
188
  - test/macros/validates_url_test.rb
186
- - test/rails/active_record_test.rb
187
189
  - test/rails/active_record_test_helper.rb
190
+ - test/rails/association_validation_test.rb
191
+ - test/rails/base_validation_overrides_test.rb
188
192
  - test/rails/macros/validates_uniqueness_test.rb
189
193
  - test/skippable_validation_test.rb
190
194
  - test/teststrap.rb