格式化字符串输入数据库的方式

时间:2010-12-14 02:58:53

标签: ruby-on-rails ruby string forms

我想以某种方式格式化输入到我的数据库的字符串列(容易混淆地命名为time)的数据。由于此项目中的遗留数据问题,我不能简单地从字符串更改列类型,因为我会丢失旧条目。

我只想要求输入表格然后提交给数据库的信息格式如下:

00:00 where a 0 can by any integer 0-9.

我如何在form_for内完成此操作。

我使用的是Rails 2.3.8。

3 个答案:

答案 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获取时间值并将其转换为时间对象。

有两个缺点:

  1. Time.parse(“12:34”)会给你类似的东西:2010-12-14 12:34:00 +0800 因为你只给了hr和min,其他字段都不可靠。
  2. 数据库中有一个名为old_time的近乎弃用的字段。因此,在您确信所有old_time值已转换为time字段后,您可能希望将来完全删除该字段。
  3. 还有一点需要注意:

    您应该为可能使用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_timelinessvalidates_date_time。我还找到了time_select with 12 hour time and Time Zone in Ruby on Rails。你也可以search Stack Overflow