2009-07-23 66 views
1

我在模型中有一段代碼,它根據運行該方法的當天時間設置開始日期和結束日期。如何不在我的模型中重複此代碼

讓我們直接進入代碼示例:

#MODEL 
now = Time.now 
if now.hour >= 17 && now.hour <= 23 
    #night 
    n = now+1.day 
    startd = Time.local(now.year, now.month, now.day, 17, 00, 00) 
    endd = Time.local(n.year, n.month, n.day, 8, 00, 00) 
elsif now.hour >= 0 && now.hour <= 7 
    #morning 
    n = now-1.day 
    startd = Time.local(n.year, n.month, n.day, 8, 00, 00) 
    endd = Time.local(now.year, now.month, now.day, 17, 00, 00)  
end 

然後模型(相同或其他)裏面,我想運行一個發現裏面這個功能。

#MODEL(SAME OR OTHER) 
Model.find(:all, 
:conditions => ['created_at >= ? AND created_at <= ?', startd, endd]) 

的問題是,我要使用該功能來設置開始和結束日期的很多,我不知道在哪裏放置它不重複自己。它將用於不同的模型。

感謝您的任何幫助。

回答

3

您可以將其包含在lib目錄中的模塊中。 RAILS_ROOT/lib中的所有ruby文件都會自動加載。

# time_calculations.rb 

module TimeCalculations 
    def calc_start_and_end_times 
    now = Time.now 
    if now.hour >= 17 && now.hour <= 23 
     #night 
     n = now+1.day 
     startd = Time.local(now.year, now.month, now.day, 17, 00, 00) 
     endd = Time.local(n.year, n.month, n.day, 8, 00, 00) 
    elsif now.hour >= 0 && now.hour <= 7 
     #morning 
     n = now-1.day 
     startd = Time.local(n.year, n.month, n.day, 8, 00, 00) 
     endd = Time.local(now.year, now.month, now.day, 17, 00, 00)  
    end 
    [startd, endd] 
    end 
end 

# model.rb 

class Model < ActiveRecord::Base 
    extend TimeCalculations 

    def self.my_find() 
    startd, endd = calc_start_and_end_times 
    Model.find(:all, 
     :conditions => ['created_at >= ? AND created_at <= ?', startd, endd]) 
    end 

end 

編輯,以反映最終的/正確的答案。

+0

這聽起來像是一個很好的解決方案,我已經嘗試過,但它給了我「未定義的方法'calc_start_and_end_times'for#」錯誤。我將模塊包含在模型類的頂部。任何想法? – mickey 2009-07-23 14:20:05

+0

嘗試更改def self.calc_start_and_end_times以確定calc_start_and_end_times 我不記得您是否需要自定義方法定義。 – erik 2009-07-23 14:48:53

+0

也試過,抱歉不提。這聽起來像模型不能從模塊訪問該方法。 – mickey 2009-07-23 15:10:11

0

可以模型類裏面添加方法find_by_date_range(startd,endd),並使用Model.find_by_date_range(的東西,something_else)

+0

那麼,計算開始和結束日期時間的部分在哪裏? – mickey 2009-07-23 14:20:59

+0

讓我解釋一下。首先你需要決定 - 在你的代碼的其他地方使用開始/結束計算。如果是 - 移動方法將很有用,負責計算開始和結束。下一步 - 在你的模型中開發find-method,它會根據你的標準返回所有記錄(erik已經進入了很好的例子)。 另一個有用的解決方案 - 您可以使用named_scope - http://apidock.com/rails/ActiveRecord/NamedScope/ClassMethods/named_scope – 2009-07-24 06:41:32

+0

更正我的評論 - 「如果是的話 - 移動方法將是有用的,負責計算開始和結束的模塊,如果沒有 - 它不是必要的「 – 2009-07-24 06:43:57

1

最簡單的方法是將您的代碼添加到模塊,也許在一個初始化:

module SmartDates 

    def start_date 
    now = Time.now 
    if now.hour >= 17 && now.hour <= 23 
     #night 
     n = now+1.day 
     return Time.local(now.year, now.month, now.day, 17, 00, 00) 
    elsif now.hour >= 0 && now.hour <= 7 
     #morning 
     n = now-1.day 
     return Time.local(n.year, n.month, n.day, 8, 00, 00) 
    end 
    end 

    def end_date 
    now = Time.now 
    if now.hour >= 17 && now.hour <= 23 
     #night 
     n = now+1.day 
     return Time.local(n.year, n.month, n.day, 8, 00, 00) 
    elsif now.hour >= 0 && now.hour <= 7 
     #morning 
     n = now-1.day 
     return Time.local(now.year, now.month, now.day, 17, 00, 00) 
    end 
    end 

end 

# Now include your module 
ActiveRecord::Base.include(SmartDates) 
ActionController::Base.include(SmartDates) 

現在start_dateend_date在模型和控制器都可用。

+0

謝謝,模塊代碼進入/ lib?包含代碼怎麼樣,你會把它放在哪裏? – mickey 2009-07-23 14:24:02

+0

我可能會把它放在一個初始化器中,就像我上面提到的那樣。在'config/initializers/smart_dates.rb'中。也許我會把模塊放在lib /和包含在初始化器中。 – mixonic 2009-07-23 15:26:17