2016-04-27 67 views
1

我在這裏有一些代碼工作正常,但它不是很安全的情況下,錯誤,特別是Exception: Timezone::Error::GeoNames產生的Timezone寶石,其中非常偶爾寶石未能檢索時區來自提供的座標。紅寶石在軌道上。正確驗證和救援的代碼在出現錯誤

用戶可以創建演出,其中包括location屬性。位置是,地址和地理編碼器將此地址轉換爲latitudelongitude

latitudelongitude然後可演出已被保存後,所以在我的控制,我有:

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 .................. 

這裏時區寶石查找與座標的時區,演出會保存後。這通常工作沒有問題,但偶爾會引發錯誤(Exception: Timezone::Error::GeoNames),可能暫時找不到服務器。

如何在保存後自動執行此代碼,但在發生故障時有回退,並將gigzonetime設置爲UTC(默認導軌時區)。

模型before_validation,因爲它拋出一個Timezone::Error::InvalidZone誤差作爲longitudelatitude屬性arn't尚無不起作用。 Geocoder文檔建議使用after_validation,所以這是它們不可用的原因。

我覺得這可能是一個簡單的解決方案,但我越來越糊塗了。

回答

0

我不明白你爲什麼不能使用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 
+0

我犯了一個錯誤。如果使用before_validation,錯誤是不一樣的。使用before_validation時的錯誤是Timezone :: Error :: InvalidZone,因爲經度和緯度屬性尚不可用。 Geocoder文檔建議after_validation去做它的魔力。你提供的救援碼看起來非常像我需要的。 –