我现在面临一个问题很久了。我的代码如下:
class BrokenModel < ActiveRecord::Base
validates_with BrokenValidator
has_many :association_name
end
class BrokenValidator < ActiveModel::Validator
def validate record
@record = record
check_alerted
end
private
def check_alerted
return if @record.association_name.to_a.empty?
alerted = <test for alerted>
if alerted
@record.errors[:base] << "It was alerted recently"
end
p "check_alerted: #{@record.errors[:base]}"
end
end
worker.rb
[...]
BrokenModel.create(association_name: [model1, model2])
[...]
在我最后一次打印的日志中显示验证仅传递了一次,但实际上我为此模型创建了多个条目,并显示association_name
。
我的环境在多个线程和多个核心中运行它,但由于条目是彼此分开创建的,因此它不是并发问题,除非分离线程中的异常影响模型创建。
出于好奇的缘故,这是在Sidekiq工作中运行。
修改
所以我在日志中注意到它可能是一个并发问题。所以这是正在发生的事情:
如果ActiveModel :: Validator中存在任何类型的线程不安全,或者其他线程可能会覆盖/共享@record,那么有什么线索吗?
答案 0 :(得分:2)
向记录添加错误不会使其无效。实际上,在保存之前验证模型时,所有先前的错误(包括您在代码中添加的错误)都将被删除。
在模型中进行此验证...不在工作人员中。
validate :check_alerted
def check_alerted
return if association_name.to_a.empty?
alerted = test
if <test for alerted>
errors.add(:base, "It was alerted recently")
end
end