我这里有一些工作正常的代码,但在出现错误的情况下不是很安全,特别是Exception: Timezone::Error::GeoNames
时区 gem 生成的,其中 gem 偶尔无法从提供的坐标中检索时区。
用户可以创建演出,其中包括具有location
属性的演出。位置是和地址,地理编码器将此地址转换为latitude
和longitude
。
保存演出后,latitude
和longitude
可用,因此在我的控制器中,我有:
if @gig.save
timezone = Timezone.lookup(@gig.latitude, @gig.longitude)
@gig.update_attributes(timezone: timezone)
if @gig.timezone
gigzonetime = @gig.date - @gig.date.in_time_zone(@gig.timezone).utc_offset
@gig.update_attributes(gigzonetime: gigzonetime)
else
gigzonetime = @gig.date
@gig.update_attributes(gigzonetime: gigzonetime)
end
bla bla bla ..................
在这里,时区 gem 在保存演出后使用坐标查找时区。这通常没有问题,但偶尔会抛出错误(Exception: Timezone::Error::GeoNames
),可能是在暂时找不到服务器时。
如何在保存后自动执行此代码,但在失败时进行回退,并将 gigzonetime 设置为 UTC(默认轨道时区)。
模型中的before_validation
不起作用,因为它会引发Timezone::Error::InvalidZone
错误,因为longitude
和latitude
属性尚不可用。地理编码器文档建议使用after_validation
因此这就是它们不可用的原因。
我觉得可能有一个简单的解决方案,但我变得混乱了。
我不明白为什么你不能使用before_validation
只要你有办法从错误中拯救出来。另外,您有理由在保存后这样做吗?之前这样做是有意义的,以避免两次写入数据库:
# `before_validation :set_timezone` should also work
before_save :set_timezone
def set_timezone
# Do geocoding...
rescue Timezone::Error::GeoNames => e
self.gigzonetime = "UTC" # Or whatever
end