2011-06-27 8 views
5

He tenido varios problemas con varios sitios en los últimos años con los usuarios poniendo espacios en el inicio/fin de los campos de texto y cadena. A veces, esto causa problemas de formato/formato, a veces causan problemas de búsqueda (es decir, el orden de búsqueda se ve mal, aunque en realidad no es así), a veces bloquean la aplicación.ActiveRecord: haga que todos los campos de texto tengan llamadas antes de guardarlos, a menos que se especifique lo contrario

Pensé que sería útil, en lugar de poner un montón de devoluciones de llamada before_save como lo he hecho en el pasado, agregar algunas funcionalidades a ActiveRecord para llamar automáticamente a .strip en cualquier cadena/campo de texto antes de guardar, a menos que dígale que no lo haga, por ejemplo, con do_not_strip :field_x, :field_y o algo similar en la parte superior de la definición de la clase.

Antes de ir y descubrir cómo hacer esto, ¿alguien ha visto una solución más agradable? Para ser claro, ya sé que puedo hacer esto:

before_save :strip_text_fields 

def strip_text_fields 
    self.field_x.strip! 
    self.field_y.strip! 
end 

pero yo estoy buscando una manera más agradable.

aplausos, máximo

Respuesta

1

He escrito un plugin para este fin hace algún tiempo. No lo he probado por un tiempo y no tiene pruebas, por lo que no hay garantías de que todavía funcione. El aspecto positivo sería un modelo limpio:

class Story < ActiveRecord::Base 
    strip_strings :title, :abstract, :text 
end 
+0

Muchas gracias @Wukerplank, lo he incorporado y parece que hace el trabajo :) Supongo que es mejor desde el punto de vista menos sorprendente enumerar explícitamente los campos de texto que quiero quitar en los modelos, en lugar de que enumerar los que no quiero quitar como originalmente. Por cierto, el enlace de instalación en la página de tu complemento no funciona: creo que solo necesitas reemplazar "https" con "git" al comienzo. También hay una izquierda sobrante, presumiblemente para la depuración? ¡aclamaciones! max –

+0

Sí, también pensé que declarar explícitamente los campos sería un modelo más legible. Y gracias por los consejos, lo limpiaré :) – Wukerplank

+0

¿Dónde agregaste el Stripper? Lo puse en lib/modules y no está cargando –

10

Aquí hay un módulo práctico que podría incluir en lib e incluir en sus modelos. No tiene las excepciones que mencionó, pero busca un método strip! que sea lo suficientemente bueno. Puede agregar la función de excepciones con bastante facilidad, si es necesario.

# lib/attribute_stripping.rb 
module AttributeStripping 

    def self.included(context) 
    context.send :before_validation, :strip_whitespace_from_attributes 
    end 

    def strip_whitespace_from_attributes 
    attributes.each_value { |v| v.strip! if v.respond_to? :strip! } 
    end 

end 

uso como esto:

class MyModel < ActiveRecord::Base 
    include AttributeStripping 

    # ... 
end 

ACTUALIZACIÓN (09/10/2013):

Revisando esta respuesta un par de años más tarde, ver cómo los vientos han cambiado. Hay una forma más limpia de hacerlo ahora. Crear un módulo de la siguiente manera:

module AttributeStripper 

    def self.before_validation(model) 
    model.attributes.each_value { |v| v.strip! if v.respond_to? :strip! } 
    true 
    end 

end 

y establecer su método que se invoca en el momento adecuado en su modelo:

class MyModel < ActiveRecord::Base 
    before_validation AttributeStripper 

    # ... 
end 

Este módulo es fácil poner a prueba ya que no es un mixin.

+0

Para construir en este ver http://edgeguides.rubyonrails.org/active_record_validations.html#custom-validators – MCB

+0

Parece que no funciona con 'Model # update'. El atributo se elimina pero en realidad no llega a la base de datos. No puedo entender por qué. Llamar a 'Model # save' parece funcionar bien. – Dex

2

He tratado este tipo de problemas de integridad de datos en diversas aplicaciones.

Solía ​​manipular la entrada de esa manera.

Pero ahora, el mejor consejo que he visto y seguido es almacenar lo que el usuario escriba. Luego haga postprocesamiento en el back-end para hacer la tira. Cree campos de base de datos adicionales (destrip) si realmente lo desea en la tabla del modelo de la base de datos.

La razón principal de esto es una cosa (primaria): cuando los usuarios quieren volver a visitar sus datos, es decir, editan, normalmente esperan ver lo que escribieron. Una razón secundaria es que evitará la posibilidad que su tira no funciona bien y destruye los datos o realmente arroja un error.

Cuestiones relacionadas