2013-05-28 3 views
5

Ich arbeite an einem Projekt mit einem Rails API und einem iOS - Client, wobei das Feld aktualisiert_at als Referenz verwendet wird, um Änderungen auf dem Server zu erkennen letzter Zug vom Kunden.ActiveRecord: Millisekunden werden nicht berücksichtigt, wenn eine where - Klausel verwendet wird

Die updated_at Datetime hat eine Genauigkeit in Millisekunden bedeutet, dass

Model.updated_at.to_f 

kehrt so etwas wie "1368977381,063427". Dies wird an den Client gesendet, der wie folgt formatiert ist: "2013-05-19T15: 29: 41.063427000Z".

Das Problem ist, wenn ich diese Datetime zurück vom Client, parse es und Abfrage mit ihm, die Millisekunden sind verloren.

last_update = DateTime.strptime("2013-05-19T15:29:41.063427000Z", "%Y-%m-%dT%H:%M:%S.%N%z") 
Model.where("updated_at > ?", last_update) 

ist so gut wie zu tun

last_update = DateTime.strptime("2013-05-19T15:29:41Z", "%Y-%m-%dT%H:%M:%S%z") 
Model.where("updated_at > ?", last_update) 

Als Ergebnis habe ich immer mindestens ein Ergebnis, wenn ich keine bekommen sollte, weil die Millisekunden abgeschnitten.

Wie kann ich diese in meiner Abfrage berücksichtigen? Versuchen

Antwort

5

Model.where("updated_at > ?", last_update.strftime("%Y-%m-%dT%H:%M:%S.%N%z")) 

Sie auch durch das Setzen (dh in einem initiallizer) dieses Format als Standardformat für Datetime in Datenbanken festlegen:

Time::DATE_FORMATS[:db]= '%Y-%m-%dT%H:%M:%S.%N%z' 

dann Ihre ursprüngliche Abfrage funktioniert wieder:

Model.where("updated_at > ?", last_update) 

Siehe Rails API für DateTime.to_s (aka .t o_formated_s)

+0

Lies es und dachte "Natürlich!" :) – Nycen

+0

Mein Problem war, dass die Genauigkeit des Zeitstempels in der Datenbank auf 5 Dezimalstellen lag, während mein Client den Zeitstempel auf 3 Dezimalstellen speicherte ... wenn eine Größer als Abfrage ausgeführt wurde, würde immer derselbe Datensatz zurückgegeben wegen der zusätzlichen 2 Dezimalstellen. – JBlake

+1

Ich bin überrascht, dass es keine nativere Möglichkeit gibt, Millisekunden in Rails zu unterstützen. : -/ –

1

Wenn Sie den ISO8601-Standard verwenden, können Sie .iso8601(10) verwenden. Ich weiß nicht warum, aber es wird standardmäßig auf Sekunden abgerundet.