ruby-on-rails - Rubocop 唯一性验证应该使用唯一索引,在从某些特定值开始的值中
问题描述
我有一个验证 order_number 值唯一性的 rails 模型,应该从 1_000_000 开始,所以我添加了一个用作第一个值的变量:
# order model
STARTING_NUMBER = 1_000_000
validates :order_number, uniqueness: true
当我通过 Rubocop 检查我的代码时,我遇到了一个错误:
app/models/order.rb:3:3: C: Rails/UniqueValidationWithoutIndex: Uniqueness validation should be with a unique index.
validates :order_number, uniqueness: true
我通过添加disable/enable
Rubocop 评论来修复它:
STARTING_NUMBER = 1_000_000
# rubocop:disable Rails/UniqueValidationWithoutIndex
validates :order_number, uniqueness: true
# rubocop:enable Rails/UniqueValidationWithoutIndex
有更好的解决方案吗?
解决方案
正确的解决方法是通过迁移向数据库添加唯一索引:
def change
add_index :orders, :order_number, unique: true
end
这将解决根本问题并防止 Rubocop 抱怨。
在 Active Record 模型中定义唯一性验证时,还应该为列添加唯一索引。有两个原因首先,即使定义了 Active Record 的验证,也可能出现重复记录。其次,会导致查询慢。
Rubocop 发现您有一个唯一性验证,但没有在您的db/schema.rb
. 模型中的唯一性验证受竞争条件的影响,因此您仍然可以获得重复值。
Rubocop 告诉您在数据库中添加唯一索引/约束以确保唯一性。Rails 指南说同样的话:
它不会在数据库中创建唯一性约束,因此可能会发生两个不同的数据库连接为您打算唯一的列创建具有相同值的两条记录。为避免这种情况,您必须在数据库中的该列上创建唯一索引。
验证还将执行潜在的昂贵数据库查询,因此无论如何您确实希望对该列进行索引,不妨将其设为唯一索引以确保您使用它时的数据完整性(损坏的代码是临时的,损坏的数据是永远的)。
不要压制警告,解决它。
推荐阅读
- javascript - 如何访问响应和获取的结果?
- c# - 扩展 C# Worker 服务以处理多个配置
- python - 带有 Tensorflow Hub 的 Keras 模型在保存/恢复时不会给出相同的结果
- distributed-system - 和弦指表是如何初始化的?
- html - 定位绝对元素不可见
- javascript - 如何使用 Javascript 将菜单连接到显示器?
- ocaml - 如何在 Ocaml 中将列表的元素组合成一个元素?
- c++ - 为什么我的函数以向量数组作为参数没有给出任何值?
- java - 当我尝试使用 setVariable 在类中设置变量时,它没有设置它
- node.js - 每次扫描 fs.watch NodeJS 后保存文件结构?