uniqueness validation raises error for persisted record without pk.
Closes #21304. While we can validate uniqueness for record without primary key on creation, there is no way to exclude the current record when updating. (The update itself will need a primary key to work correctly).
This commit is contained in:
parent
013dd756e1
commit
50e4afff20
@ -1,3 +1,10 @@
|
||||
* Uniqueness validator raises descriptive error when running on a persisted
|
||||
record without primary key.
|
||||
|
||||
Closes #21304.
|
||||
|
||||
*Yves Senn*
|
||||
|
||||
* Add a native JSON data type support in MySQL.
|
||||
|
||||
Example:
|
||||
|
@ -218,11 +218,12 @@ def initialize(errors)
|
||||
class UnknownPrimaryKey < ActiveRecordError
|
||||
attr_reader :model
|
||||
|
||||
def initialize(model)
|
||||
super("Unknown primary key for table #{model.table_name} in model #{model}.")
|
||||
def initialize(model, description = nil)
|
||||
message = "Unknown primary key for table #{model.table_name} in model #{model}."
|
||||
message += "\n#{description}" if description
|
||||
super(message)
|
||||
@model = model
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Raised when a relation cannot be mutated because it's already loaded.
|
||||
|
@ -18,7 +18,11 @@ def validate_each(record, attribute, value)
|
||||
|
||||
relation = build_relation(finder_class, table, attribute, value)
|
||||
if record.persisted? && finder_class.primary_key.to_s != attribute.to_s
|
||||
relation = relation.where.not(finder_class.primary_key => record.id)
|
||||
if finder_class.primary_key
|
||||
relation = relation.where.not(finder_class.primary_key => record.id)
|
||||
else
|
||||
raise UnknownPrimaryKey.new(finder_class, "Can not validate uniqueness for persisted record without primary key.")
|
||||
end
|
||||
end
|
||||
relation = scope_relation(record, table, relation)
|
||||
relation = relation.merge(options[:conditions]) if options[:conditions]
|
||||
|
@ -4,6 +4,7 @@
|
||||
require 'models/warehouse_thing'
|
||||
require 'models/guid'
|
||||
require 'models/event'
|
||||
require 'models/dashboard'
|
||||
|
||||
class Wizard < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
@ -446,4 +447,26 @@ def self.name
|
||||
key2.key_number = 10
|
||||
assert_not key2.valid?
|
||||
end
|
||||
|
||||
def test_validate_uniqueness_without_primary_key
|
||||
klass = Class.new(ActiveRecord::Base) do
|
||||
self.table_name = "dashboards"
|
||||
|
||||
validates_uniqueness_of :dashboard_id
|
||||
|
||||
def self.name; "Dashboard" end
|
||||
end
|
||||
|
||||
abc = klass.create!(dashboard_id: "abc")
|
||||
assert klass.new(dashboard_id: "xyz").valid?
|
||||
assert_not klass.new(dashboard_id: "abc").valid?
|
||||
|
||||
abc.dashboard_id = "def"
|
||||
|
||||
e = assert_raises ActiveRecord::UnknownPrimaryKey do
|
||||
abc.save!
|
||||
end
|
||||
assert_match(/\AUnknown primary key for table dashboards in model/, e.message)
|
||||
assert_match(/Can not validate uniqueness for persisted record without primary key.\z/, e.message)
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user