Rails 为保存在数据库中创建唯一值
Rails create unique value for saving in database
我的意思是不检查保存的是当前值 - 唯一。
我如何创造价值(例如在我的模型中),检查它是否对我的 table 是独一无二的。 Anf id 也许不尝试创造新的价值。并再次检查唯一性
现在我的模型中有以下代码:
after_initialize :init
def init
self.some_field = rand(1..99_999_999).to_s
end
添加验证
然后设置值,检查一下,
如果好:完成。
如果不是: 再试一次,重复合理的次数。
像这样
validates :some_field, uniqueness: true
def init
attempts = 0
loop do
self.some_field << SecureRandom.uuid.to_s[0..16]
self.valid?
break unless self.errors[:some_field].any?
attempts = attempts + 1
if attempts > 3
self.errors[:some_field] << "Could not generate a unique value after #{attempts} attempts"
break
end
end
end
您可以像这样使用模型回调,
before_create :generate_some_field
def generate_some_field
self.some_field = loop do
random = rand(1..99_999_999).to_s
break random unless ModelName.exists?(some_field: random)
end
end
添加唯一性验证,并在验证前初始化字段。添加最大重试限制,以避免当记录数接近或达到可能的随机值的最大数量时可能出现的死锁。
INITIALIZATION_MAX_RETRIES = 10
before_validation :initialize_fields
validates_uniqueness_of :some_field
private
def initialize_fields
unless some_field
retries = 0
loop do
retries += 1
break if retries > INITIALIZATION_MAX_RETRIES
self.some_field = rand(1..99_999_999).to_s
break unless self.class.find_by(some_field: some_field)
end
end
end
我最近写了一个gem来为自己解决这个问题:https://github.com/inem/shufflino
此方法不需要重试或额外的 SQL 查询。
我还建议观看 this talk 主题。
我的意思是不检查保存的是当前值 - 唯一。
我如何创造价值(例如在我的模型中),检查它是否对我的 table 是独一无二的。 Anf id 也许不尝试创造新的价值。并再次检查唯一性
现在我的模型中有以下代码:
after_initialize :init
def init
self.some_field = rand(1..99_999_999).to_s
end
添加验证
然后设置值,检查一下,
如果好:完成。
如果不是: 再试一次,重复合理的次数。
像这样
validates :some_field, uniqueness: true
def init
attempts = 0
loop do
self.some_field << SecureRandom.uuid.to_s[0..16]
self.valid?
break unless self.errors[:some_field].any?
attempts = attempts + 1
if attempts > 3
self.errors[:some_field] << "Could not generate a unique value after #{attempts} attempts"
break
end
end
end
您可以像这样使用模型回调,
before_create :generate_some_field
def generate_some_field
self.some_field = loop do
random = rand(1..99_999_999).to_s
break random unless ModelName.exists?(some_field: random)
end
end
添加唯一性验证,并在验证前初始化字段。添加最大重试限制,以避免当记录数接近或达到可能的随机值的最大数量时可能出现的死锁。
INITIALIZATION_MAX_RETRIES = 10
before_validation :initialize_fields
validates_uniqueness_of :some_field
private
def initialize_fields
unless some_field
retries = 0
loop do
retries += 1
break if retries > INITIALIZATION_MAX_RETRIES
self.some_field = rand(1..99_999_999).to_s
break unless self.class.find_by(some_field: some_field)
end
end
end
我最近写了一个gem来为自己解决这个问题:https://github.com/inem/shufflino
此方法不需要重试或额外的 SQL 查询。
我还建议观看 this talk 主题。