我想以某种方式格式化输入到我的数据库的字符串列(容易混淆地命名为time
)的数据。由于此项目中的遗留数据问题,我不能简单地从字符串更改列类型,因为我会丢失旧条目。
我只想要求输入表格然后提交给数据库的信息格式如下:
00:00 where a 0 can by any integer 0-9.
我如何在form_for
内完成此操作。
我使用的是Rails 2.3.8。
答案 0 :(得分:1)
解决这个问题可能会有所帮助:
首先创建一个迁移:
rename_column :the_models, :time, :old_time
add_column :the_models, :time, :time
现在,该模型将包含一个名为old_time
的字段,其中包含原始时间数据,以及一个具有正确字段类型的新time
字段。
因此,现有表单似乎总是丢失数据,但至少他们正在调用the_model.time
来获得结果。
关于部分的真正工作:
class TheModel < ActiveRecord::Base
def time
read_attribute(:time) || Time.parse(read_attribute(:old_time))
end
end
现在,时间值将保存到time
字段中。
当time
为零时,它会尝试从old_time
获取时间值并将其转换为时间对象。
有两个缺点:
2010-12-14 12:34:00 +0800
因为你只给了hr和min,其他字段都不可靠。old_time
的近乎弃用的字段。因此,在您确信所有old_time
值已转换为time
字段后,您可能希望将来完全删除该字段。还有一点需要注意:
您应该为可能使用text_field的:time
字段转换现有表单。
text_field可能会显示2010-12-14 12:34:00 +0800
。
如果你真的还想使用text_field,你可以:
def time
t = read_attribute(:time)
t.nil? ? read_attribute(:old_time) : t.strftime("%H:%M")
end
def time=(val)
write_attribute(:time, Time.parse(val))
end
答案 1 :(得分:0)
你的正则表达式是/\d\d:\d\d/
,但我不确定如何在Ruby中使用正则表达式。
答案 2 :(得分:0)
你的正则表达式是:
/[0-9]{2}:[0-9]{2}/
或
/\d\d:\d\d/
以下是一些测试:
'00:00'[/[0-9]{2}:[0-9]{2}/] # => "00:00"
'12:00'[/\d\d:\d\d/] # => "12:00"
'11:59'[/[0-9]{2}:[0-9]{2}/] # => "11:59"
'23:59'[/\d\d:\d\d/] # => "23:59"
':'[/[0-9]{2}:[0-9]{2}/] # => nil
':0'[/[0-9]{2}:[0-9]{2}/] # => nil
'0:0'[/[0-9]{2}:[0-9]{2}/] # => nil
'000:0'[/[0-9]{2}:[0-9]{2}/] # => nil
'0:000'[/[0-9]{2}:[0-9]{2}/] # => nil
到目前为止,我正在使用您指定的解决方案,但现在它已经崩溃了:
# BUG?
'1:00'[/[0-9]{2}:[0-9]{2}/] # => nil
# Fix?
'1:00'[/[0-9]{1,2}:[0-9]{2}/] # => "1:00"
# *** BUG ***
'99:99'[/[0-9]{2}:[0-9]{2}/] # => "99:99"
请注意,'99:99'已被接受。
在处理类似时间值的事情时,尝试使用正则表达式来检查范围并不是非常可行。它可以完成,但正则表达式变得丑陋。
这是解决方案的开始。完成适当范围的测试留给读者练习:
timeval = '00:00'[/[0-9]{2}:[0-9]{2}/]
(timeval.split(':').map(&:to_i) <=> [11,59]) <= 0 # => true
timeval = '1:00'[/[0-9]{1,2}:[0-9]{2}/]
(timeval.split(':').map(&:to_i) <=> [11,59]) <= 0 # => true
timeval = '1:00'[/[0-9]{1,2}:[0-9]{2}/]
(timeval.split(':').map(&:to_i) <=> [11,59]) <= 0 # => true
timeval = '0:99'[/[0-9]{1,2}:[0-9]{2}/]
(timeval.split(':').map(&:to_i) <=> [11,59]) <= 0 # => true
timeval = '99:99'[/[0-9]{1,2}:[0-9]{2}/]
(timeval.split(':').map(&:to_i) <=> [11,59]) <= 0 # => false
或者,您可能希望使用一些<select>
popups for the values或一个专为时间输入设计的jQuery插件,或validates_timeliness
或validates_date_time
。我还找到了time_select with 12 hour time and Time Zone in Ruby on Rails。你也可以search Stack Overflow。