Umgang mit Säulenkonvertierungen in Ruby Activerecord
-
27-10-2019 - |
Frage
Wenn ich mich mit einer Legacy -Datenbank befasste, bin ich in einer SQL -Server -Datenbank auf eine Spalte gestoßen, in der das Datum als Dezimalstelle gespeichert wird. EG 2011-04-23 wird als 20110423.0 gespeichert.
Gibt es einen allgemeinen ActivereCord -Mechanismus für den Umgang mit "seltsamen" Spaltespeicherkonventionen? Enum-ähnliche Säulen, in denen sie tatsächlich als Ganzzahlen gespeichert werden, sind ein weiterer Fall, der auch denselben Mechanismus verwenden könnte, aber ich kann nicht ganz finden, wonach ich suche.
Es scheint, als ob Serialisierung mich teilweise dorthin bringt:
class Thing < ActiveRecord::Base
class DecimalDate
def load(date)
if date.is_a? Numeric
y,m,d = /^(\d\d\d\d)(\d\d)(\d\d)/.match(date.to_s)[1..3].map(&:to_i)
Date.civil(y,m,d)
end
end
def dump(date)
date ? date.strftime('%Y%m%d').to_i : 0
end
end
serialize :weird_date, DecimalDate
end
rails c
> Thing.first.weird_date
=> Sun, 02 Jan 2011
Aber die Illusion ist dünn. Die Kolumne weiß nicht, dass es sich um ein Datum handelt, das als Dezimalzahl gespeichert ist. ZB Vergleiche scheitern:
rails c
> Thing.where('weird_date > ?', 1.week.ago)
...
ActiveRecord::StatementInvalid: ... Error converting data type varchar to numeric.:
Lösung
Wenn Sie gezwungen sind, mit Legacy -Daten umzugehen, sehe ich zwei Möglichkeiten, diese zu verwalten.
1 aus Ihrer Datenbank
Sie können Ihre Daten "konvertieren", indem Sie Ihre Tabelle ansehen, die Ihre (Datums-) Felder im laufenden Flug konvertieren. Anschließend erstellen Sie in dieser Ansicht einen Auslöser (vor Einfügen/Aktualisierung), der Ihre Daten in Ihr altes Format umwandelt. Schließlich sagen Sie Activerecord, dass Sie Ihre Ansicht anstelle Ihrer Tabelle verwenden sollen.
2 aus Ihrer Bewerbung (Schienen)
Finden Sie einen Weg, um Activerecord zu sagen, dass er den gleichen Job machen soll. Haben Sie bereits versucht, es mit AR -Rückrufen mit zu verwalten? After_initialize und vor_save? Mehr Informationen hier