2014-09-30 105 views
2

我想嘗試從params獲取日期到日期格式,如果它不能,那麼我想然後將它分配給今天一年的日期。嘗試生成無效日期的Ruby字符串日期to_date

這是我試過的。

valid_until = params[:valid_until].try(:to_date) || Date.today.next_year 

try方法是很酷,因爲如果:valid_until日期是零它只會返回nil。我發現的是,如果有人有一個無效的日期,如「4790224374」,那麼它將返回一個ArgumentError作爲無效日期。 :valid_until的日期仍然會針對to_date運行。

我想這有一個救援似乎是唯一的答案,只是想知道是否有一個更聰明的方法來嘗試迎合nils和無效的日期錯誤,然後將其設置爲明年的默認設置。

編輯:

您可以閱讀上漲約 Try here

您可以閱讀上漲約 to_date here

+0

你可以在'||'處放置一個'rescue',也許放下'try'?這將是相當整潔,但我認爲缺點是所有的例外都會被捕獲。 – 2014-09-30 15:20:12

+0

是的,我在想什麼。它有點棘手。這可能會很快變得凌亂,我花了最後一點時間看幾個想法,但似乎都增加了幾行。 – TheLegend 2014-09-30 15:22:04

+1

當你不使用紅寶石核心,你可否請包括你正在使用的圖書館,以協助那些誰想要幫助:) – 2014-09-30 15:27:07

回答

2

你濫用Object.try。如果某個方法不存在於某個對象上,此方法意味着無提示失敗。在這種情況下,該方法在那裏(所以它被稱爲)並且該方法失敗。

這並不意味着要取代嘗試/救援塊。下面是一個可能的實現。

def expiration_date(a_string) 
    Date.parse(a_string) 
rescue 
    Date.today.next_year 
end 

valid_until = expiration_date(params[:valid_until]) 
1

除非是某種代碼高爾夫,我不會試圖在一個班輪儘可能榨取儘可能多的邏輯。此外,您可能希望儘可能讓您的控制器精益求精。爲什麼不用一些理智的面向對象的直覺來告訴你:「如果我無法弄清楚這裏的邏輯,也許我應該把它提取出來,以分離方法或類」? F.i.

# app/services/expirer.rb 
class AccountExpirer 
    def self.expiration_date(user_input) 
    return Date.today.next_year unless user_input.present? 
    begin 
     Date.parse(user_input) 
    rescue ArgumentError 
     Date.today.next_year 
    end 
    end 
end 

# some controller 
valid_until = AccountExpirer.expiration_date(params[:valid_until]) 

但是,如果您需要告訴用戶他已輸入無效數據,我不會停在這裏。您可以使用ActiveModel::Modelhttp://api.rubyonrails.org/classes/ActiveModel/Model.html)擴展您的班級,這將允許您編寫適當的驗證,並在您的表單中使用它(就像AR模型一樣)。

+0

厄內斯特,我很好奇你的方法和我的。你是否有任何理由選擇只捕獲ArgumentErrors,而不是僅僅拯救所有東西,而是針對nil(這會產生TypeError)。 – 2014-09-30 16:02:45

+0

@JeffPrice如果我誠實的話,我不會開始/營救。但是你沒有提供任何信息,關於你是否強制執行日期格式或其他期望,所以我的第一個想法是使用Date.parse,並捕獲拋出的異常(Date.parse在「無效」日期將拋出ArgumenError ,而不是,fi日期:InvalidDateError - 這是因爲這種方法不是一個驗證者)。我的觀點不同,即這種邏輯不應該留在控制器中。 – Ernest 2014-09-30 16:12:44

+0

此控制器handels上傳,並沒有一個模型來運行任何驗證。但你絕對正確。捕獲在控制器級別驗證的數據是一種不好的做法,將行爲提取到服務中也是一個不錯的主意。謝謝! – TheLegend 2014-09-30 16:43:11

相關問題