2009-07-23 17 views
1

Ich habe dieses Codeelement in einem Modell, das ein Startdatum und ein Enddatum entsprechend der Tageszeit festlegt, zu der die Methode ausgeführt wird.Wie kann ich diesen Code nicht in meinen Modellen wiederholen?

Lassen Sie uns springen rechts in den Codebeispiel:

#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 

dann in einem Modell (gleich oder einen anderen), Ich versuche, diese Funktion in einem Fund zu laufen.

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

Das Problem ist, dass ich diese Funktion verwenden, werde die Start- und Ende viel geht, und ich weiß nicht, wo es zu platzieren mich nicht wiederholen. Es wird von verschiedenen Modellen verwendet werden.

Danke für jede Hilfe.

Antwort

3

Sie können es in ein Modul im Verzeichnis lib aufnehmen. Alle Ruby-Dateien in RAILS_ROOT/lib werden automatisch geladen.

# 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 

Edited final/richtige Antwort zu reflektieren.

+0

Das klang wie eine gute Lösung, ich habe das schon versucht, aber es gab mir "undefined Methode' calc_start_and_end_times 'für # "Fehler. Ich habe das Modul über meiner Modellklasse eingefügt. Irgendeine Idee? – mickey

+0

Versuchen Sie, def self.calc_start_and_end_times zu def calc_start_and_end_times zu ändern Ich konnte mich nicht erinnern, ob Sie selbst oder nicht auf der Methodendefinition benötigen. – erik

+0

Versuchte das auch, Entschuldigung dafür, nicht zu erwähnen. Es klingt, als ob das Modell vom Modul aus nicht auf die Methode zugreifen kann. – mickey

0

Sie Methode find_by_date_range hinzufügen (Startd, ENDD) innerhalb Modellklasse und verwenden Model.find_by_date_range (etwas, something_else)

+0

Also, wo ist der Teil, der die Start- und Enddatumszeit berechnet? – mickey

+0

Lass mich das erklären. Zuallererst müssen Sie sich entscheiden, ob Sie an anderen Stellen in Ihrem Code beginnen/enden. Wenn ja - wird es nützlich sein, die Methode zu verschieben, die für Berechnungen von Anfang und Ende verantwortlich ist. Nächster Schritt - Entwerfen Sie die Find-Methode in Ihrem Modell, die alle Datensätze nach Ihren Kriterien zurückgibt (erik ist ein gutes Beispiel). Und noch eine weitere hilfreiche Lösung - Sie können named_scope - http://apidock.com/rails/ActiveRecord/NamedScope/ClassMethods/named_scope –

+0

Korrektur für meinen Kommentar verwenden - "Wenn ja - es wird nützlich sein, die Methode zu verschieben, die verantwortlich für Berechnungen von Anfang und Ende des Moduls, wenn nicht - es ist nicht so notwendig –

1

Der einfachste Weg ist, Ihren Code zu einem Modul hinzufügen möchten, vielleicht in einem Initialisierer:

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) 

Jetzt start_date und end_date sind beide verfügbar bei den Modellen und Controllern.

+0

Danke, der Modulcode geht in/lib? Was ist mit dem Include-Code, wo würdest du ihn hinstellen? – mickey

+0

Ich würde es wahrscheinlich in einen Initialisierer setzen, wie ich oben erwähnt habe. In 'config/initializers/smart_dates.rb' oder etwas.Vielleicht würde ich das Modul in Lib/und die Includes in den Initialisierer setzen. – mixonic

Verwandte Themen