mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Translate adapter errors that indicate a violated uniqueness constraint to ActiveRecord::RecordNotUnique exception derived from ActiveReecord::StatementInvalid.
Signed-off-by: Michael Koziarski <michael@koziarski.com>
This commit is contained in:
parent
18a97a6601
commit
53a3eaa860
6 changed files with 47 additions and 1 deletions
|
@ -67,6 +67,10 @@ module ActiveRecord #:nodoc:
|
|||
class StatementInvalid < ActiveRecordError
|
||||
end
|
||||
|
||||
# Raised when a record cannot be inserted because it would violate a uniqueness constraint.
|
||||
class RecordNotUnique < StatementInvalid
|
||||
end
|
||||
|
||||
# Raised when number of bind variables in statement given to <tt>:condition</tt> key (for example, when using +find+ method)
|
||||
# does not match number of expected variables.
|
||||
#
|
||||
|
|
|
@ -211,9 +211,14 @@ module ActiveRecord
|
|||
@last_verification = 0
|
||||
message = "#{e.class.name}: #{e.message}: #{sql}"
|
||||
log_info(message, name, 0)
|
||||
raise ActiveRecord::StatementInvalid, message
|
||||
raise translate_exception(e, message)
|
||||
end
|
||||
|
||||
def translate_exception(e, message)
|
||||
# override in derived class
|
||||
ActiveRecord::StatementInvalid.new(message)
|
||||
end
|
||||
|
||||
def format_log_entry(message, dump = nil)
|
||||
if ActiveRecord::Base.colorize_logging
|
||||
if @@row_even
|
||||
|
|
|
@ -563,6 +563,17 @@ module ActiveRecord
|
|||
where_sql
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def translate_exception(exception, message)
|
||||
case exception.errno
|
||||
when 1062
|
||||
RecordNotUnique.new(message)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def connect
|
||||
encoding = @config[:encoding]
|
||||
|
|
|
@ -941,6 +941,15 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def translate_exception(exception, message)
|
||||
case exception.message
|
||||
when /duplicate key value violates unique constraint/
|
||||
RecordNotUnique.new(message)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
# The internal PostgreSQL identifier of the money data type.
|
||||
MONEY_COLUMN_TYPE_OID = 790 #:nodoc:
|
||||
|
|
|
@ -431,6 +431,16 @@ module ActiveRecord
|
|||
'INTEGER PRIMARY KEY NOT NULL'.freeze
|
||||
end
|
||||
end
|
||||
|
||||
def translate_exception(exception, message)
|
||||
case exception.message
|
||||
when /column(s)? .* (is|are) not unique/
|
||||
RecordNotUnique.new(message)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class SQLite2Adapter < SQLiteAdapter # :nodoc:
|
||||
|
|
|
@ -130,4 +130,11 @@ class AdapterTest < ActiveRecord::TestCase
|
|||
assert_equal " LIMIT 1,7 OFFSET 7", @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)
|
||||
end
|
||||
end
|
||||
|
||||
def test_uniqueness_violations_are_translated_to_specific_exception
|
||||
@connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
|
||||
assert_raises(ActiveRecord::RecordNotUnique) do
|
||||
@connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue