为什么 "uniqueness: true" 验证在我的测试中不起作用 (Rails)?
Why is the "uniqueness: true" validation not working in my test (Rails)?
在我的 Rails 应用程序中,我试图为属于不同用户的设备保存 MAC 地址。每个 MAC 地址都必须是唯一的,所以我包括了唯一性验证。
验证本身似乎有效,因为当我尝试使用 Rails 控制台 (ActiveRecord::RecordNotUnique
) 时重复记录被拒绝。但是,我检查是否只能保存唯一记录的测试失败了。
所以我的问题是:
- 为什么我的测试失败了,我该如何解决?
- 我在别处读到,单靠唯一性验证并不是确保唯一性的可靠方法。我应该使用其他方法,例如
before_save
回调吗?
这是我收到的测试错误消息:
Expected #<MacAddress id: nil, user_id: nil, address: "MACADD123", created_at: nil, updated_at: nil> to be nil or false
我的模型文件中的设置:
# app/models/mac_address.rb
class MacAddress < ApplicationRecord
validates :address, uniqueness: true
belongs_to :user
end
# app/models/user.rb
class User < ApplicationRecord
has_many :mac_addresses, dependent: :destroy
end
测试以检查唯一性:
class MacAddressTest < ActiveSupport::TestCase
test 'mac address must be unique' do
new_mac = 'MACADD123'
assert MacAddress.create(user: User.first, address: new_mac)
assert MacAddress.all.pluck(:address).include?(new_mac)
# The 'assert_not' below is failing.
assert_not MacAddress.create(user: User.second, address: new_mac)
end
end
提前感谢您的帮助。
根据the documentation on create
:
请注意,该记录没有 id
。它没有被坚持。使用 .errors.full_messages
检查错误以查看唯一性验证失败。
The resulting object is returned whether the object was saved successfully to the database or not.
您应该断言它已保存,例如:
mac_address = MacAddress.create(...)
assert !mac_address.new_record?
告诉您它是否已保存的位置。或者,您可以使用 create!
如果失败,它将提高 ActiveRecord::RecordInvalid
。
为了将来参考和查看此问题的任何人 - 我用 save
而不是 create
重写了我的测试,如下所示:
test 'mac address must be unique' do
test_address = 'MACADD123'
original_mac = MacAddress.new(user: User.first, address: test_address)
duplicate_mac = MacAddress.new(user: User.second, address: test_address)
assert original_mac.save
assert MacAddress.pluck(:address).include?(test_address)
assert_not duplicate_mac.save
duplicate_mac.errors.messages[:address].include?('has already been taken')
end
在我的 Rails 应用程序中,我试图为属于不同用户的设备保存 MAC 地址。每个 MAC 地址都必须是唯一的,所以我包括了唯一性验证。
验证本身似乎有效,因为当我尝试使用 Rails 控制台 (ActiveRecord::RecordNotUnique
) 时重复记录被拒绝。但是,我检查是否只能保存唯一记录的测试失败了。
所以我的问题是:
- 为什么我的测试失败了,我该如何解决?
- 我在别处读到,单靠唯一性验证并不是确保唯一性的可靠方法。我应该使用其他方法,例如
before_save
回调吗?
这是我收到的测试错误消息:
Expected #<MacAddress id: nil, user_id: nil, address: "MACADD123", created_at: nil, updated_at: nil> to be nil or false
我的模型文件中的设置:
# app/models/mac_address.rb
class MacAddress < ApplicationRecord
validates :address, uniqueness: true
belongs_to :user
end
# app/models/user.rb
class User < ApplicationRecord
has_many :mac_addresses, dependent: :destroy
end
测试以检查唯一性:
class MacAddressTest < ActiveSupport::TestCase
test 'mac address must be unique' do
new_mac = 'MACADD123'
assert MacAddress.create(user: User.first, address: new_mac)
assert MacAddress.all.pluck(:address).include?(new_mac)
# The 'assert_not' below is failing.
assert_not MacAddress.create(user: User.second, address: new_mac)
end
end
提前感谢您的帮助。
根据the documentation on create
:
请注意,该记录没有 id
。它没有被坚持。使用 .errors.full_messages
检查错误以查看唯一性验证失败。
The resulting object is returned whether the object was saved successfully to the database or not.
您应该断言它已保存,例如:
mac_address = MacAddress.create(...)
assert !mac_address.new_record?
告诉您它是否已保存的位置。或者,您可以使用 create!
如果失败,它将提高 ActiveRecord::RecordInvalid
。
为了将来参考和查看此问题的任何人 - 我用 save
而不是 create
重写了我的测试,如下所示:
test 'mac address must be unique' do
test_address = 'MACADD123'
original_mac = MacAddress.new(user: User.first, address: test_address)
duplicate_mac = MacAddress.new(user: User.second, address: test_address)
assert original_mac.save
assert MacAddress.pluck(:address).include?(test_address)
assert_not duplicate_mac.save
duplicate_mac.errors.messages[:address].include?('has already been taken')
end