Ruby on rails 在Ruby ActiveRecord中处理列转换
在处理遗留数据库时,我遇到了SQL Server数据库中的一列,其中日期存储为十进制。例如,2011-04-23存储为20110423.0 是否有一个通用的ActiveRecord机制来处理“奇怪”的列存储约定?类似枚举的列实际上存储为整数,这是另一种可能也使用相同机制的情况,但我无法完全找到我要查找的内容 似乎序列化让我部分达到了目的:Ruby on rails 在Ruby ActiveRecord中处理列转换,ruby-on-rails,ruby,activerecord,legacy-database,Ruby On Rails,Ruby,Activerecord,Legacy Database,在处理遗留数据库时,我遇到了SQL Server数据库中的一列,其中日期存储为十进制。例如,2011-04-23存储为20110423.0 是否有一个通用的ActiveRecord机制来处理“奇怪”的列存储约定?类似枚举的列实际上存储为整数,这是另一种可能也使用相同机制的情况,但我无法完全找到我要查找的内容 似乎序列化让我部分达到了目的: class Thing < ActiveRecord::Base class DecimalDate def load(date)
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
如果您被迫处理遗留数据,我认为有两种方法可以对其进行管理 1从您的数据库中删除 您可以通过创建表的视图来“转换”数据,该视图可以动态转换(日期)字段。然后(在插入/更新之前)在此视图上执行触发器,将数据转换回旧格式。最后,告诉ActiveRecord使用视图而不是表 2来自您的应用程序(Rails)
找到一种方法告诉ActiveRecord做同样的工作。您是否已尝试在初始化后使用和保存前使用使用AR回调来管理它?更多信息如果您被迫处理遗留数据,我认为有两种方法可以对其进行管理 1从您的数据库中删除 您可以通过创建表的视图来“转换”数据,该视图可以动态转换(日期)字段。然后(在插入/更新之前)在此视图上执行触发器,将数据转换回旧格式。最后,告诉ActiveRecord使用视图而不是表 2来自您的应用程序(Rails)
找到一种方法告诉ActiveRecord做同样的工作。您是否已尝试在初始化后使用和保存前使用使用AR回调来管理它?更多信息能否将数据迁移到Rails支持的约定?或者你是被迫去处理它的?你能把所有对怪异日期的访问隐藏在你的东西里面吗?这至少会使怪诞的地方化。@basgys:不幸的是,被迫处理它。@muistoshort:这可能是可能的。看起来Rails会有一些我想要的功能。每次我在Rails中处理遗留数据库时,都会遇到类似的情况。(我给出的“enum as int”示例,以及另一个SQL Server DB,其中boolean是正确的“bit”列。)但enum和boolean值是驱动程序级别的问题,而不是应用程序级别的问题。您可以尝试将日期修补到字符串管理器,但这可能会导致更多问题。我认为模型之外的任何东西都不应该调用
where
(尽管有普遍的做法),但我对适当的分层持固执和偏执的态度:)您能将数据迁移到Rails支持的约定吗?或者你是被迫去处理它的?你能把所有对怪异日期的访问隐藏在你的东西里面吗?这至少会使怪诞的地方化。@basgys:不幸的是,被迫处理它。@muistoshort:这可能是可能的。看起来Rails会有一些我想要的功能。每次我在Rails中处理遗留数据库时,都会遇到类似的情况。(我给出的“enum as int”示例,以及另一个SQL Server DB,其中boolean是正确的“bit”列。)但enum和boolean值是驱动程序级别的问题,而不是应用程序级别的问题。您可以尝试将日期修补到字符串管理器,但这可能会导致更多问题。我认为模型之外的任何东西都不应该调用where
(尽管有常见的做法),但我对适当的分层持固执和偏执的态度:)
rails c
> Thing.where('weird_date > ?', 1.week.ago)
...
ActiveRecord::StatementInvalid: ... Error converting data type varchar to numeric.: