Я просмотрел API и провел две ночи, уставившись на этот код, и, к сожалению, хотя я чувствую, что близок к решению, я не могу заставить его работать. У меня есть модель, представляющая смены, которые среди других атрибутов имеют время начала.
create_table "shifts", :force => true do |t|
t.datetime "start"
Пользователь взаимодействует с этим как с простым временем, так как дата устанавливается в другом месте, поэтому я настроил виртуальные средства доступа для получения и установки.
class Shift < ActiveRecord::Base
def start_time
start.strftime("%H:%M")
end
def start_time=(time)
date = start.midnight
self.start = add_string_time_to_date(date, time)
end
def add_string_time_to_date(date, string_time)
t = DateTime.strptime(string_time, "%H:%M")
DateTime.new(date.year, date.month, date.mday, t.hour, t.min)
end
end
Все это прекрасно работает при манипулировании через стандартный контроллер с @shift.update_attributes(params[:shift])
, если ввести время в ожидаемом формате.
Я хотел бы проверить введенный формат времени, но он не так прост, как при использовании метода, описанного ниже, так как strptime()
вызывает ArgumentError до того, как проверка будет достигнута.
validates :start_time, :format => { :with => /^([0-1][0-9]|[2][0-3]):([0-5][0-9])$|^/,
:message => "Invalid format." }
Я могу обойти это, поместив условный вызов в start_time()
, например, в приведенном ниже примере, но на самом деле это не работает удовлетворительно по двум причинам.
def start_time=(time)
if time =~ /^([0-1][0-9]|[2][0-3]):([0-5][0-9])$|^/
date = start.midnight
self.start = add_string_time_to_date(date, time)
else
errors.add :start, "format invalid."
nil
end
end
Сначала ActiveRecord, похоже, не знает, что установщик не прошел. Я делаю это из факта, что update_attributes () в контроллере возвращает, как будто все было хорошо, даже если это не так. Во-вторых, обратная связь с пользователем не возвращается, поэтому вызов error.add, вероятно, находится вне контекста. Это также немного некрасиво.
Требуемая функциональность - это стандартная валидация, поэтому в случае неудачи пользователь видит ошибку в форме так же, как и при любой другой неудаче валидации. Короче говоря, как мне достичь этой функциональности, и правильно ли я к ней подхожу?
Нужно ли вызывать конкретное исключение, чтобы уведомить ActiveRecord о сбоях, и если да, то где это лучше всего сделать? Лучше всего просто спасти и использовать вспышку?