2009-07-23 7 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 

その後(同じまたは別の)モデルの内側に、私は、find内部でこの関数を実行しようとしています。

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

問題

は、私はスタートを設定するには、その関数を使用するつもりだと終わりは多くのことをさかのぼり、そして私は自分自身を繰り返さないためにそれを配置する場所を知らないということです。それは別のモデルから使用される予定です。

ありがとうございました。

答えて

3

libディレクトリのモジュールに含めることができます。 RAILS_ROOT/libにあるすべてのルビファイルが自動的に読み込まれます。

# 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 'を与えました。モデルクラスの上にモジュールを含めました。何か案が? – mickey

+0

def self.calc_start_and_end_timesをdef_calc_start_and_end_timesに変更してみてください メソッド定義に自分自身が必要かどうかはわかりませんでした。 – erik

+0

あまりにもそれを試して、申し訳ありませんが言及しないために。モデルからモジュールのメソッドにアクセスできないように思えます。 – mickey

0

あなたが最も簡単な方法は、多分初期化子で、モジュールにコードを追加することであるモデルクラス内のメソッドのfind_by_date_range(STARTD、ENDD)を追加し、Model.find_by_date_range(何か、something_else)

+0

開始日と終了日時を計算する部分はどこですか? – mickey

+0

私を説明させてください。まず、あなたが決定する必要がある - あなたのコードのどこかで使用される開始/終了の計算になります。 「はい」の場合は、開始と終了の計算を担当するメソッドを移動すると便利です。次のステップ - モデル内のfindメソッドを開発します。これは、あなたの基準に基づいてすべてのレコードを返します(erikは良い例を入力しました)。 さらに便利なソリューション - 名前付きスコープを使用できます - http://apidock.com/rails/ActiveRecord/NamedScope/ClassMethods/named_scope –

+0

私のコメントを修正しました - "そうなら、メソッドを移動すると便利ですモジュールの開始と終了の計算、そうでない場合 - それは必要ではありません " –

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

+0

私はおそらく上記のようにイニシャライザに入れます。 'config/initializers/smart_dates.rb'か何かで。おそらく私はモジュールをlib /に入れて、イニシャライザにインクルードします。 – mixonic

関連する問題