Форматирование способа ввода строки в мою базу данных - PullRequest
1 голос
/ 14 декабря 2010

Я хочу отформатировать данные, введенные в строковый столбец (озадаченно названный time) моей базы данных определенным образом.Из-за устаревших проблем с данными в этом проекте я не могу просто изменить тип столбца со строки на время, потому что я потеряю старые записи.

Я просто хочу потребовать, чтобы формат информации, введенной в форму и затем переданной в базу данных, был следующим:

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

Как бы я поступилчто в пределах form_for.

Я использую Rails 2.3.8.

Ответы [ 3 ]

1 голос
/ 14 декабря 2010

Обходной путь, который может помочь:

Сначала создайте миграцию, выполнив:

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 Поскольку вы указали только часы и минуты, другие поля ненадежны.
  2. В базе данных есть почти устаревшее поле с именем old_time. Поэтому в будущем вы можете захотеть полностью удалить это поле после того, как будете уверены, что все значения old_time были преобразованы в поле time.

Еще одно примечание:

Вы должны преобразовать существующие формы для поля :time, которое, вероятно, использует text_field. Поле text_ может показывать что-то вроде 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
0 голосов
/ 14 декабря 2010

Ваше регулярное выражение будет:

/[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> всплывающие окна для значений , или плагин jQuery, предназначенный для ввода времени, или что-то вроде validates_timeliness или validates_date_time. Я также нашел time_select с 12-часовым временем и часовым поясом в Ruby on Rails . Вы также можете искать переполнение стека .

0 голосов
/ 14 декабря 2010

Ваше регулярное выражение будет /\d\d:\d\d/, но я не уверен, как использовать регулярные выражения в Ruby.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...