He rastreado la API y pasé dos noches mirando este código y, lamentablemente, mientras percibo que estoy cerca del solución, no puedo hacer que funcione. Tengo un modelo que representa los cambios, que entre otros atributos tienen una hora de inicio.Capturando una excepción planteada en el acceso personalizado antes de llegar a la validación del modelo (y mostrándola al usuario en errores [])
create_table "shifts", :force => true do |t|
t.datetime "start"
el usuario interactúa con esto como un tiempo simple como la fecha se establece en otro lugar, por lo que han establecido métodos de acceso virtuales para obtener y definir.
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
Todo esto funciona bien cuando se manipula a través de un controlador estándar con @shift.update_attributes(params[:shift])
uno provisto entra en el momento en el formato esperado.
Me gustaría validar el formato de hora introducido, pero no es tan simple como usar el método de abajo ya que strptime()
levanta un ArgumentError antes de que se alcance la validación.
validates :start_time, :format => { :with => /^([0-1][0-9]|[2][0-3]):([0-5][0-9])$|^/,
:message => "Invalid format." }
puedo trabajar alrededor de esto poniendo una llamada condicional en start_time()
como el ejemplo a continuación, pero que en realidad no funciona de manera satisfactoria por dos razones.
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
First ActiveRecord parece no saber que el sistema ha fallado. Lo deduzco del hecho de que update_attributes() en el controlador regresa como si todo estuviera bien, aunque no fuera así. En segundo lugar, no se devuelve ningún comentario al usuario, por lo que la llamada a errors.add probablemente esté fuera de contexto. También es un poco feo.
La funcionalidad deseada es la de una validación estándar, por lo que si falla el usuario ve un error en el formulario al igual que con cualquier otro error de validación. En resumen, ¿cómo puedo lograr esta funcionalidad, y me estoy acercando a esto de la manera correcta?
¿Debo plantear una excepción específica para notificar a ActiveRecord de problemas y, de ser así, cuál es la mejor manera de hacerlo? Lo mejor es solo rescatar y usar el flash?