Rails y las validaciones

Supongo que ya lo sabiamos todos …

http://drawohara.com/post/18926188

… pero validar un objeto en Rails no quiere decir que no podamos
insertarlo dos veces o más en la base de datos.

En un proyecto en el que estuve trabajando hace unas semanas se
insertaban los objetos tantas veces como procesos mongrel habia
corriendo en el servidor, y realmente me volví loco encontrando el
fallo. Al final metí el “constraint” en la base de datos y el sistema
acabó funcionando como debia.

Bueno, eso es todo, simplemente queria compartir una pequeña
experiencia.

Un saludo,

Francesc


Not sent from my iPhone

Francesc E. wrote:

Supongo que ya lo sabiamos todos …

http://drawohara.com/post/18926188

… pero validar un objeto en Rails no quiere decir que no podamos
insertarlo dos veces o m�s en la base de datos.

Vaya, yo no lo sabía. Gracias por la info :wink:

2008/3/6 Edgar J. Suarez [email protected]:

Francesc E. wrote:

Supongo que ya lo sabiamos todos …

http://drawohara.com/post/18926188

… pero validar un objeto en Rails no quiere decir que no podamos
insertarlo dos veces o m�s en la base de datos.

Vaya, yo no lo sabía. Gracias por la info :wink:

Una cosa que siempre he oido de Rails es que es monohilo precisamente
porque ActiveRecord es monohilo. Todas las aplicaciones Rails tiene un
gran lock antes de entrar en ejecución para evitar estas condiciones
de carrera. En el ejemplo está creando varios hilos que acceden de
manera simultanea a la misma clase ActiveRecord, por lo que si
ActiveRecord no está diseñado para ese uso no me extraña que falle.

De cualquier forma, el autor sí que da un buen consejo: siempre que se
pueda las comprobaciones tanto en el código de la aplicación como en
la base de datos. A pesar de que DHH es de la opinión de que la BD no
hace nada más que almacenar datos, obviamente está equivocadísimo
(como en muchas otras cosas).

Si algún experto en el código de ActiveRecord se pasa por aquí podría
explicar si se supone que el ejemplo tendría que funcionar bien o
Rails no lo garantiza.

On Mar 6, 2008, at 20:56 , Daniel R. Troitiño wrote:

Una cosa que siempre he oido de Rails es que es monohilo precisamente
porque ActiveRecord es monohilo. Todas las aplicaciones Rails tiene un
gran lock antes de entrar en ejecución para evitar estas condiciones
de carrera.

El problema es que una aplicacion web Rails ordinaria es multi-
proceso, a efectos de race conditions de ese tipo da lo mismo.

2008/3/6 Daniel R. Troitiño [email protected]:

A pesar de que DHH es de la opinión de que la BD no
hace nada más que almacenar datos, obviamente está equivocadísimo
(como en muchas otras cosas).

No puedo estar más en desacuerdo con tu afirmación. David Heinemeier
siempre ha dicho que las cosas son como son porque el las necesita
asi
. Si tu contexto, aplicaciones o soluciones necesitan que el
framework sea diferente… cambialo. Suena duro… pero el Open Source
es así.

Personalmente, y habiendo dedicado casi una década al trabajo con
erps, sistemas legados y otras cosas aburridas del estilo no puedo
coincidir más con él sobre el tema de la lógica en la base de datos.
En el contexto de aplicaciones web, que están integradas con otras a
nivel de aplicación y no de BD, la lógica no puede estar en mejor
sitio que en el código, ni mas ni menos.

Pero entendiendo que cada aplicación es un mundo no puedo decir que
estas equivocadísimo, solo que en la mayoría de nuevas aplicaciones
web… estoy con David.


Kind Regards,
Aitor Garcia
Cofounder - Linking Paths
http://www.linkingpaths.com

A pesar de que DHH es de la opinión de que la BD no
hace nada más que almacenar datos, obviamente está equivocadísimo
(como en muchas otras cosas).

Yo creo que esta afirmación tiene una doble lectura, efectivamente la BD
solo hace eso y no sería necesario que validara nada si nuestra
aplicación se comportara correctamente, ejecutara las validaciones
correctamente, controlara las excepciones correctamente… Nadie puede
asegurar que una aplicación se comporte como se espera en el 100% de los
casos, por tanto , yo creo que es necesario implementar seguridad a bajo
nivel, básicamente porque el coste en tiempo es ridículo y nos puede
salvar de tener problemas graves.

Si por un error de las validaciones de Rails corrompemos una tabla con 1
millon de registros que pasa?

Yo no me arriesgo la verdad.

“Valida a bajo nivel y dormirás más tranquilo”

Un saludo


Emili Parreño
www.eparreno.com

Buenas,

explicar si se supone que el ejemplo tendría que funcionar bien o
Rails no lo garantiza.

Usando AR lo que se puede hacer es tener una columna (por defecto
lock_version) para hacer bloque optimista. En ese caso, cada vez que se
lee un registro se lee la versión del lock, y cada vez que se actualiza
Rails lo incrementa automáticamente. De ese modo, si en un proceso
leíste una versión pero otro proceso distinto ha hecho un update
después, cuando intentes guardar tendrás una excepción.

Lo que no sé es si las validaciones internamente respetan el mecanismo
de lock o no. En caso de hacerlo, podría ser una opción (obviamente en
ningún caso sustituye, sino que complementa, a la de bajo nivel de tener
la seguridad implementada a nivel de DB).

saludos,

javier ramírez

2008/3/6 Emili Parreño [email protected]:

Nadie puede
asegurar que una aplicación se comporte como se espera en el 100% de los
casos,

Postgres, Oracle, Mysql, etc, etc… tampoco son la piedra filosofal
de los resultados perfectos. Nada de lo hecho por el hombre es
perfecto, y las BDs tampoco. Sin embargo… ¿como de facil es testar tu
aplicación? ¿como de facil es testar la logica de
triggers/constraints/functions en la BD?. Testar el software es lo que
lo hace seguro.

por tanto , yo creo que es necesario implementar seguridad a bajo
nivel, básicamente porque el coste en tiempo es ridículo y nos puede
salvar de tener problemas graves.

El coste en tiempo de implementación puede ser pequeño. El de
mantenimiento (el mas importante) no tanto, recordemos que no estamos
hablando solo de unos checks por aquí y por alla. Y de cualquier
manera volvemos a lo mismo… hay que testar.

Si por un error de las validaciones de Rails corrompemos una tabla con 1
millon de registros que pasa?
Yo no me arriesgo la verdad.
“Valida a bajo nivel y dormirás más tranquilo”

Umm… imagino que lo del millón de registros era para dar ¿énfasis?.
En tablas de cientos de filas también hay datos importantes, ¿no?.
Asumamos nuestra responsabilidad como programadores y no la delegemos
en terceros (ni maquinas ni personas).


Kind Regards,
Aitor Garcia
Cofounder - Linking Paths
http://www.linkingpaths.com

2008/3/6 Emili Parreño [email protected]:

nivel, básicamente porque el coste en tiempo es ridículo y nos puede
salvar de tener problemas graves.

Pobre Codd [1] … debe estar reviviendo para venir a pegarnos un poco
:slight_smile:

Base de datos relacional[2] :Entre las ventajas de este modelo están:

  1. Garantiza herramientas para evitar la duplicidad de registros, a
    través de campos claves o llaves.
  2. Garantiza la integridad referencial: Así al eliminar un registro
    elimina todos los registros relacionados dependientes.
  3. Favorece la normalización por ser más comprensible y aplicable.

Es por eso que usamos bases de datos relacionales, no porque MySQL es
muy chulo, o porque postgreSQL es muy rapido o porque MS SQL Server
corre mejor sobre Windows.

[1] Edgar Frank Codd - Wikipedia, la enciclopedia libre
[2] Modelo relacional - Wikipedia, la enciclopedia libre

Que es eso de “Constraints belongs to database” :wink:

Saludo,

Francesc

On Mar 6, 2008, at 10:52 PM, Emili Parreño wrote:

asegurar que una aplicación se comporte como se espera en el 100% de
Yo no me arriesgo la verdad.
Ror-es mailing list
[email protected]
simplelogica.net


Not sent from my iPhone

“Constraints belongs to database” que no se de donde lo saqué pero es
la manera de evitar ciertas situaciones. Recuerdo hace unas semanas
hablando con Xavier N. que comentaba el problema de mi
aplicación.
¡Se generaban tantas entradas como mongrels habia corriendo en la
maquina!

Investigué y la solución rapida fué meterle el constraint en la base
de datos.

Si DataMapper es thread-safe … se supone que esto no pasa, o me
equivoco?

En fin, que Rails no es perfecto, pero es que tiene esos pequeños
detalles que tanto nos gustan.

Un saludo,

Francesc

On Mar 6, 2008, at 9:37 PM, javier ramirez wrote:

actualiza

javier ramírez


Ror-es mailing list
[email protected]
simplelogica.net


Not sent from my iPhone

Daniel,

Te escribo de manera privada para ver si me puedes aclarar la
sigiuente
afirmación:
2008/3/6 Daniel R. Troitiño [email protected]:

…pero el modelo
relacional (relaciones y restricciones de integridad) es comprobable
matemáticamente… ¡así que no tienes que comprobar, simplemente
demostrar que es correcto! (sí, lo se es una tarea de chinos, pero a
diferencia del código Ruby el modelo relacional es decidible).

Me puedes decir, ¿cómo se comprueba matemáticamente esto? Fui a la
clase de BD y sin embargo, no recuerdo haber tratado nunca el tema. Me
interesaría saber por qué aseguras que un modelo relacional es
decidible, nunca lo había oído.
No lo estoy intentando poner en duda, tengo curiosidad honesta y si me
pudieras dar más información al respecto te lo agradecería, me
interesa saber sobre la “Türing-completitud” de las BDs :slight_smile:

Gracias

PD: No te respondo directamente a la lista por considerarlo off-topic.

Creo que mi afirmación se entendió mal.

Conozco perfectamente la postura de David sobre “su” framework y,
aunque no me parece la más adecuada en un proyecto de la envergadura
de Rails, la respeto: si alguien necesita algo, que se lo haga el
mismo. Creedme, llevo algunos años utilizando (y cuando puedo
ayudando) software libre y a veces me pone de los nervios esta idea.

Pero que David mantega esa postura no le asigna automáticamente la
razón en todo lo relativo en su framework; una de las cosas en las que
no tiene razón es que algunas de las validaciones de los registros es
necesario e imprescindible realizarlas en la base de datos (y
alguién en el hilo ya ha nombrado a uno de los padres de las bases de
datos relacionales, asignatura que David no debió cursar).

Una validación como validates_format_of me parece mucho mejor hacerla
en el código sí y solo sí nada más que mí código va a acceder a la
BBDD, simplemente porque el código en Ruby es mucho más expresivo y
más fácil que un constraint SQL, sobre todo para cosas un poco
complicadas.

Pero resulta que una validación como validates_uniqueness_of no solo
trata con un dato de tu registro por separado, sino que compara un
dato de tu registro con todos los demas datos ya almacenados en la
BBDD. El problema de realizar esta comprobación en Rails es el típico
problema de threads y mutexes de programación de sistemas, entre que
tu recoges el dato, lo compruebas y almacenas el resultado otro thread
puede haber escrito un nuevo dato y hacer que tu comprobación sea
incorrecta. Alguién podría pensar que con una transacción esto se
podría arreglar, pero como hace notar el autor del artículo, los
propios save de Rails utilizan una transación, que en casos como los
que describo no sirven para nada.

El único punto donde se puede hacer esa comprobación es la BBDD y eso
te lo puede decir cualquiera que atendiese a sus clases de BBDD: el
sistema gestor de BBDD es el único elemento que puede garantizar que
se cumplen las integridad de los datos que almacena.

Por cierto, Aitor se preguntaba por ahí arriba como de sencillo es
comprobar la lógica de triggers/constraints/functions de la BBDD. No
voy a hablar de triggers y functions en la BBDD porque me parece que
son añadidos “frankestein” al modelo relacional, pero el modelo
relacional (relaciones y restricciones de integridad) es comprobable
matemáticamente… ¡así que no tienes que comprobar, simplemente
demostrar que es correcto! (sí, lo se es una tarea de chinos, pero a
diferencia del código Ruby el modelo relacional es decidible).

Siento el rollazo y siento el malentendido.

2008/3/6 Federico B. [email protected]

Te escribo de manera privada para ver si me puedes aclarar la
sigiuente afirmación:

Y yo que pensaba hacerlo de manera privada…:stuck_out_tongue:

Pido disculpas por el OT.

2008/3/7 Daniel R. Troitiño [email protected]:

Conozco perfectamente la postura de David sobre “su” framework y,
aunque no me parece la más adecuada en un proyecto de la envergadura
de Rails, la respeto

Precisamente es por su postura por lo que no importa un carajo la
envergadura del proyecto, y por lo que tiene razón automáticamente en
todo lo relativo en su framework. De la misma manera que yo tengo
automáticamente razón en todas las elecciones de mi ropa interior,
porque es la mía… te guste o no XD.

Pero que David mantega esa postura no le asigna automáticamente la
razón en todo lo relativo en su framework; una de las cosas en las que
no tiene razón es que algunas de las validaciones de los registros es
necesario e imprescindible realizarlas en la base de datos (y
alguién en el hilo ya ha nombrado a uno de los padres de las bases de
datos relacionales, asignatura que David no debió cursar).

Me encanta cuando os poneis radicales con eso de la verdad unica… es
tan… universal XD. Vuelvo a lo mismo… su solución a ti te puede
parecer no segura, vulnerable, puede ser no thread-safe y seguro que
mata un gatito cada vez que arrancan los mongrels en 37signals… pero
les vale. Ni mas ni menos. En ningun momento he dicho que el test que
se indicaba al principio del thread no generase efectivamente un
problema de duplicidad, sino que, de nuevo, estoy con David Heinemeier
en la opinión de que todo lo que decide que datos y por que cierto
datos se graban en la BD esta mejor en el código que en la BD
(siempre que, como decía, hablemos de aplicaciones modernas, o de
integraciones a nivel de aplicación y no de BD). La implementación es
algo puntual que se debe testar y que cambiara en el tiempo. La
opinión de David sobre las validaciones en el modelo permanecerá
aunque AR sea thread-safe.

El único punto donde se puede hacer esa comprobación es la BBDD y eso
te lo puede decir cualquiera que atendiese a sus clases de BBDD: el
sistema gestor de BBDD es el único elemento que puede garantizar que
se cumplen las integridad de los datos que almacena.

Será que yo no atendía… ummm… uhhhh… ah no!.. ¡no estaba!..
estaba instalando un ERP en Madrid, en aquella época XD. Imagino que
eso explica mi amateurismo y el de David… que entiendo infieres que
tampoco debió atender.

Por cierto, Aitor se preguntaba por ahí arriba como de sencillo es
comprobar la lógica de triggers/constraints/functions de la BBDD. No
voy a hablar de triggers y functions en la BBDD porque me parece que
son añadidos “frankestein” al modelo relacional, pero el modelo
relacional (relaciones y restricciones de integridad) es comprobable
matemáticamente…

Me ha dicho SuperCoco que te referías a lo que en la Uni llaman
“demostración formal”, que aparte de para impresionar a las tias
cuando lo dices y producir un incomodo silencio en la cafeteria en
visperas de examenes, sirve para comprobar matematicamente esta cosa
de los programas informaticos… Me gustaría que me pasases el enlace
a la demostración formal de la im-ple-men-ta-ción de Mysql o de
PostgreSql o de Oracle. ¿Porque te referias a la implementacion del
modelo no?.. yo desde luego me referia a lo que puedo tocar… que es
la implementacion… no a la nubes de algodon del sagrado cielo
relacional.

Como se que estas cosas no acaban nunca… mis disculpas, mis
constricciones, mis respetos a sus mujeres, etc, etc…


Kind Regards,
Aitor Garcia
Cofounder - Linking Paths
http://www.linkingpaths.com

2008/3/7 Federico B. [email protected]:

matemáticamente… ¡así que no tienes que comprobar, simplemente
interesa saber sobre la “Türing-completitud” de las BDs :slight_smile:

Dudo que las bases de datos sean Turing-completas, ya que son
decidibles, mientras que algo Turing-completo no lo es.

Es muy posible que no dieras nada de teoría de bases de datos en tus
clases, dependiendo si estaban más orientadas al uso de motores de
bases de datos o al estudio de los modelos relacionales. Depende de la
cátedra, como siempre.

Para la demostración se utiliza el algebra relacional, y unos cuantos
teoremas. El libro que utilicé para mis clases fue “Relational
Database Theory” de Atzeni, Batini y De Antonellis. Es pesado, pero te
explica bastante sobre el algebra relacional que está por debajo del
las bases de datos relacionales.

Pero como en todo… las demostraciones son un ejercicio académico, se
utilizan modelos sencillos, y te dicen que lo mismo sirve para modelos
más complejos, simplemente necesitas más tiempo y más paciencia.
Supongo que cualquier modelo más allá de los de ejemplo es un poco
“perdida de tiempo” demostrarlo de este modo.

Bai.

2008/3/7 Daniel R. Troitiño [email protected]:

Es muy posible que no dieras nada de teoría de bases de datos en tus
clases, dependiendo si estaban más orientadas al uso de motores de
bases de datos o al estudio de los modelos relacionales. Depende de la
cátedra, como siempre.

Por mis clases me refería a las clases a las que asistí, apenas soy un
estudiante :slight_smile:

El libro que utilicé para mis clases fue “Relational
Database Theory” de Atzeni, Batini y De Antonellis. Es pesado, pero te
explica bastante sobre el algebra relacional que está por debajo del
las bases de datos relacionales.

Gracias por la referencia, lo
miraré.

Jo, de verdad, solo era mi opinión, apoyada por lo que he estudiado y
lo que creo correcto. Creo que nos estamos saliendo un poco por la
tangente.

2008/3/7 Aitor Garcia R. [email protected]:

porque es la mía… te guste o no XD.

Tu ropa interior te afecta a tí mismo y como mucho a tu pareja (a
menos que vayas medio desnudo por la calle, claro), por lo que no veo
mayor inconveniente en que sea tu decisión, y te prometo que no me
meteré con ella. Rails es un framework que por suerte utiliza mucha
gente, y aunque en un principio fuera “su” proyecto, ahora mismo,
escuchar a los que utilizamos Rails no creo que sea malo, responder
por sistema con un “Fuck you” me parece una mala política de RRPP.

parecer no segura, vulnerable, puede ser no thread-safe y seguro que

En el caso de una sóla aplicación, con una sola base de datos, y sin
concurrencia, comprobar las cosas en el código de tu aplicación o en
el código de tu base de datos es lo mismo y no debería suceder nada
malo. Si alguna de las condiciones anteriores no se cumple, y tu data
mapper es similar al de Rails, no te puedo asegurar que tu
aplicación,por mucho testeo que le metas que mantendrá la integridad de los
datos. Desgraciadamente las aplicaciones web modernas incumplen muchas
de las condiciones.

cuando lo dices y producir un incomodo silencio en la cafeteria en
visperas de examenes, sirve para comprobar matematicamente esta cosa
de los programas informaticos… Me gustaría que me pasases el enlace
a la demostración formal de la im-ple-men-ta-ción de Mysql o de
PostgreSql o de Oracle. ¿Porque te referias a la implementacion del
modelo no?.. yo desde luego me referia a lo que puedo tocar… que es
la implementacion… no a la nubes de algodon del sagrado cielo
relacional.

La demostración forma a la que me refería (y no creo que impresione
mucho a las tias, pero sí que provoca esos incómodos silencios) es la
del modelo relacional de tu base de datos, no la de la
implementaciónde MySQL o similares (ningún programa software no sencillo es
decidible). De hecho, para más puñeta, casi ningún gestor de BBDD
“comercial” (entiendase como que se utiliza en el mundo real) te
asegura muchas de las propiedades del modelo relacional que dicen
implementar (o te las asegura con muchas restricciones). Por lo que
sí, a pesar de que demuestres que tu modelo es correcto, al utilizarlo
en la base de datos puede dejar de serlo.