rails_devs_for_data_integrity 0.1.4 → 0.1.5
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/CHANGELOG +14 -0
- data/VERSION +1 -1
- data/lib/rails_devs_for_data_integrity.rb +77 -22
- data/rails_devs_for_data_integrity.gemspec +3 -2
- metadata +3 -2
data/CHANGELOG
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
0.1.5 (2009-12-23)
|
2
|
+
* Changed: Il8n support for error messages
|
3
|
+
* Changed: Generate error messages for unique key violations based on the fields/columns derived from the mysql exception
|
4
|
+
* Changed: handle_unique_key_violation takes a scope parameter for unique keys across multiple columns
|
5
|
+
handle_unique_key_violation :field1, :scope => [:field2]
|
6
|
+
|
7
|
+
0.1.4 (2009-12-17)
|
8
|
+
* Changed: handle_unique_key_violation can take several key arguments
|
9
|
+
handle_unique_key_violation :field1, :field2
|
10
|
+
* Changed: method to handle all violations by default: ActiveRecord::Base.enable_all_database_violation_checks
|
11
|
+
|
12
|
+
0.1.3 (2009-12-16)
|
13
|
+
* Changed: Create a gem spec
|
14
|
+
* Fixed: Fix plugin to work with rails 2.0
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.5
|
@@ -33,12 +33,19 @@ module ActiveRecord::RailsDevsForDataIntegrity
|
|
33
33
|
def self.included(base)#:nodoc
|
34
34
|
base.send :class_inheritable_hash, :unique_key_check_options
|
35
35
|
base.send :class_inheritable_hash, :foreign_key_check_options
|
36
|
+
base.send :class_inheritable_hash, :default_violation_messages
|
37
|
+
|
36
38
|
base.send :attr_reader, :duplicate_exception
|
37
39
|
base.send :attr_reader, :foreign_key_exception
|
38
40
|
|
39
41
|
base.unique_key_check_options = {}
|
40
42
|
base.foreign_key_check_options = {}
|
41
|
-
|
43
|
+
base.default_violation_messages = {
|
44
|
+
:taken => 'has already been taken',
|
45
|
+
:taken_multiple => "has already been taken for {{context}}",
|
46
|
+
:taken_generic => 'Duplicate field.',
|
47
|
+
:foreign_key => "association does not exist."
|
48
|
+
}
|
42
49
|
base.extend ClassMethods
|
43
50
|
end
|
44
51
|
|
@@ -60,9 +67,12 @@ module ActiveRecord::RailsDevsForDataIntegrity
|
|
60
67
|
alias_data_integrity_methods
|
61
68
|
options = args.extract_options! || {}
|
62
69
|
options.symbolize_keys!
|
63
|
-
|
64
70
|
args.each do |name|
|
65
|
-
self.unique_key_check_options[ name.to_sym ]= options.merge(
|
71
|
+
self.unique_key_check_options[ name.to_sym ]= options.merge(
|
72
|
+
:field_name => name.to_s,
|
73
|
+
:columns => [name.to_s].
|
74
|
+
concat( (options[:scope]||[]).collect(&:to_s) ).uniq.sort
|
75
|
+
)
|
66
76
|
end
|
67
77
|
end
|
68
78
|
|
@@ -115,33 +125,78 @@ module ActiveRecord::RailsDevsForDataIntegrity
|
|
115
125
|
end
|
116
126
|
end
|
117
127
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
# we are not sure which violation occurred if we have multiple entries
|
122
|
-
# since mysql does not return a good error message
|
123
|
-
# add them all
|
124
|
-
unique_key_check_options.each do |name, options|
|
125
|
-
self.errors.add(options[:field_name], options[:message]||"has already been taken.")
|
126
|
-
end
|
128
|
+
def default_error_message_for_violation( violation_type, columns )#:nodoc:
|
129
|
+
message_key = if violation_type == :foreign_key
|
130
|
+
:foreign_key
|
127
131
|
else
|
128
|
-
|
129
|
-
|
132
|
+
case columns.length
|
133
|
+
when 0 then :taken_generic
|
134
|
+
when 1 then :taken
|
135
|
+
else :taken_multiple
|
136
|
+
end
|
130
137
|
end
|
138
|
+
I18n.translate(
|
139
|
+
:"activerecord.errors.messages.#{message_key}",
|
140
|
+
:default => default_violation_messages[ message_key ],
|
141
|
+
:context => columns.slice(1..-1).join('/')
|
142
|
+
)
|
131
143
|
end
|
132
144
|
|
133
|
-
|
134
|
-
def
|
145
|
+
# Custom error messages set with handle_violation
|
146
|
+
def custom_error_message_for_violation( violation_type, columns )#:nodoc:
|
147
|
+
options = send(
|
148
|
+
"#{violation_type}_check_options"
|
149
|
+
)[ columns.first.to_sym ] if columns.any?
|
150
|
+
|
151
|
+
message = case options[:message]
|
152
|
+
when Symbol then Il8n.translate( options[:message] )
|
153
|
+
else options[:message]
|
154
|
+
end unless options.blank?
|
155
|
+
end
|
156
|
+
|
157
|
+
# Return the error message
|
158
|
+
def error_message_for_violation( violation_type, columns )#:nodoc:
|
159
|
+
message = custom_error_message_for_violation( violation_type, columns )
|
160
|
+
message ||= default_error_message_for_violation( violation_type, columns )
|
161
|
+
end
|
135
162
|
|
136
|
-
|
137
|
-
|
138
|
-
message
|
163
|
+
def add_errors_for_violation( violation_type, columns )
|
164
|
+
columns = [columns].flatten.compact
|
165
|
+
message = error_message_for_violation( violation_type, columns )
|
139
166
|
|
140
|
-
if
|
141
|
-
self.errors.
|
167
|
+
if columns.blank?
|
168
|
+
self.errors.add_to_base( message )
|
142
169
|
else
|
143
|
-
self.errors.
|
170
|
+
self.errors.add( columns.first, message )
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def index_for_record_not_unique(exception) #:nodoc:
|
175
|
+
case exception.message
|
176
|
+
when /Duplicate entry.*for key (\d+)/
|
177
|
+
index_position = $1.to_i
|
178
|
+
# minus two b/c mysql message is one-based + rails excludes primary key index from indexes list
|
179
|
+
ActiveRecord::Base.connection.indexes(self.class.table_name)[index_position - 2]
|
180
|
+
when /Duplicate entry.*for key '(\w+)'/
|
181
|
+
index_name = $1
|
182
|
+
ActiveRecord::Base.connection.indexes(self.class.table_name).detect { |i| i.name == index_name }
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
# Add a duplicate error message to errors based on the exception
|
188
|
+
def add_unique_key_error( exception, columns = nil )
|
189
|
+
columns ||= begin
|
190
|
+
index = index_for_record_not_unique( exception )
|
191
|
+
index.columns if index
|
144
192
|
end
|
193
|
+
add_errors_for_violation( :unique_key, columns )
|
194
|
+
end
|
195
|
+
|
196
|
+
# Add a foreign key error message to errors based on the exception
|
197
|
+
def add_foreign_key_error(exception, foreign_key=nil)
|
198
|
+
foreign_key ||= foreign_key_from_error_message( exception )
|
199
|
+
add_errors_for_violation( :foreign_key, foreign_key )
|
145
200
|
end
|
146
201
|
|
147
202
|
# Return the foreign key name from the foreign key exception
|
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rails_devs_for_data_integrity}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Blythe Dunham"]
|
12
|
-
s.date = %q{2009-12-
|
12
|
+
s.date = %q{2009-12-23}
|
13
13
|
s.description = %q{Rails Devs For Data Integrity catches unique key and foreign key violations
|
14
14
|
coming from the MySQLdatabase and converts them into an error on the
|
15
15
|
ActiveRecord object similar to validation errors
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
]
|
21
21
|
s.files = [
|
22
22
|
".gitignore",
|
23
|
+
"CHANGELOG",
|
23
24
|
"MIT-LICENSE",
|
24
25
|
"README",
|
25
26
|
"Rakefile",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_devs_for_data_integrity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blythe Dunham
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-23 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -32,6 +32,7 @@ extra_rdoc_files:
|
|
32
32
|
- README
|
33
33
|
files:
|
34
34
|
- .gitignore
|
35
|
+
- CHANGELOG
|
35
36
|
- MIT-LICENSE
|
36
37
|
- README
|
37
38
|
- Rakefile
|