2010-09-15 79 views
1

我在做的東西一樣檢查無結果的ActiveRecord查詢

def ServerInfo.starttime(param) 
    find(:all, :conditions => "name ='#{param}_started'", :select => "date").first.date.to_datetime 
    end 

現在,這個問題不相關的原因,模型的幾個地方,它可以發生,這種特定的行不在數據庫和上面的代碼失敗,NoMethodError (undefined method `date' for nil:NilClass):。我目前的解決辦法是

res = find(:all, :conditions => "name ='#{param}_started'", :select => "date") 
    check_time = res.first.nil? ? 0 : res.first.date.to_datetime 

這找工作,但我覺得這是不對的灑代碼所有的地方。有沒有更多的ruby-ish/rail-ish方法來防止解除引用nil?

回答

6

爲了避免零的NoMethodError,你應該定義一個beginrescue塊,

def ServerInfo.starttime(param) 
    begin 
    find(:all, :conditions => "foo").first.date.to_datetime 
    rescue 
    0 
    end 
end 

我也很喜歡Rails的try方法:

find(:all, :conditions => "foo").first.try(:date).try(:to_datetime) || 0 
+0

我會使用try方法,這非常有用。 – 2010-09-15 14:48:12

+0

甜,不知道Rails'try'。出於簡潔的原因,我就是這麼想的。 – jhwist 2010-09-16 07:52:21

1

也許這就是清潔:

check_time = res.first.date.to_datetime if res.first 

順便說一句,不要使用:

:conditions => "name ='#{param}_started'" # SQL injection vulnerability. 

使用這個來代替:

:conditions => ["name = ?", "#{param}_started"] # This is safer. Pure clean Ruby 

它的安全

0

您可能也定義一個範圍。例如,在一個Rails3中的應用程序,你應該嘗試:

在你ServerInfo.rb型號:

scope :starttime, lambda{|param| 
    if self.has_attribute?(param+'_started') 
    where("name = ?", param+'_started').select('date') 
    else 
    false 
    end 
} 

//請記住,永遠不要把你的PARAMS直接在SQL查詢,這是不好的做法,因爲你一定風險SQL注入//

在控制器

然後:

res = ServerInfo.starttime('a_param') 
check_time = res.first.date.to_datetime if res 

我沒有嘗試的代碼,那麼你可能需要以使其適應您的需求(或您的Rails2應用程序)