这是我的before_save方法:
before_save :check_postal
def check_postal
first_three = self.postal_code[0..2]
first_three.downcase!
postal = Postal.find_by_postal_code(first_three)
if postal
self.zone_id = postal.zone_id
else
PostalError.create(postal_code: self.postal_code)
return false
end
end
self.zone_id = postal.zone_id
时一切正常,但在else
语句中,我的PostalError.create(postal_code: self.postal_code)
不会将记录保存到数据库中。
我知道它与return false
语句有关,因为当我删除它时,它会保存得很好 - 但是这会使目的失败..
如何在返回false时保存新的PostalError
记录以防止当前对象保存...
答案 0 :(得分:4)
你说得对:问题是before_save
。
整个保存过程都包含在一个事务中。如果保存失败,无论是由于验证失败,还是正在回滚异常还是其他原因,都会回滚该事务。这将撤消PostalError记录的创建。
通常这是一件好事 - 这样不完整的保存不会留下碎屑
我可以想出两种方法来解决这个问题。一种是根本不在那里创建记录:一旦危险过去,使用after_rollback钩子来执行它。
另一种方法是使用不同的数据库连接创建该记录(因为事务是每个连接事物)。一种简单的方法是使用不同的线程:
Thread.new { PostalError.create(...)}.join
我将join
放在那里,以便等待线程完成,而不是为您的应用添加一些您可能不期望的并发度。
答案 1 :(得分:-2)
我不知道,但我试图猜测解决方案。
else
PostalError.create(postal_code: self.postal_code)
self.zone_id = postal.zone_id
end