Me gustaría hacer un callback pero no se cómo llevarlo a cabo.
Tengo una tabla de destacados que tiene un campo integer “Activado”. En
toda la tabla sólo puede haber una fila con activado=1, el resto de
filas debe tener valor 0.
Bien, lo que me gustaría hacer es que antes de que se creara o se
actualizara, mirara la tabla y ver si existe un campo con valor=1, si
existe que vuelva a la plantilla mostrando el error y si no, que se
grabe.
Podría hacerlo con un begin… rescue en mi controlador, pero me
gustaría probar en el model, he visto que es con before_create o
before_update, pero no se muy bien la sintaxis de cómo leer desde el
model la tabla y si puedo usar redirect en el model para que me dirija
otra vez a la plantilla con el error si hay o qué manera hay para hacerlo.
Igual con validates_uniqueness_of puedo ponerle un valor para que no se
repita, pero no se tampoco
Alguien puede aconsejarme o ponerme un ejemplo? muchas gracias
Yo creo que con validates_uniqueness_of bastarÃa:
class Person < ActiveRecord::Base
validates_uniqueness_of :activado
…
end
Supongo que también podrÃas hacerlo en un before_algo, comprobando si
hay alguna fila con activado==1 (creo que serÃa:
self.find_first_by_activado(1)). En el caso de que esté activado alguno,
basta con lanzar una excepción y (creo) que se cancelará y no se grabará
la fila. Luego ya desde el controlador ves que no ha grabado (lanzará
una excepción o devolverá un false, según como grabes) y rediriges allÃ.
Aunque vamos, en principio la validación es mucho mejor
Saludos.
Héctor escribió:
Supongo que también podrÃas hacerlo en un before_algo, comprobando si
HabÃa pensado ya en validates_uniqueness_of, pero el resto de filas
deben tener valor 0 y este valor si se debe repetir. Si hubiera algún
modo de decirle que es sólo con 1 serÃa genial.
Héctor escribió:
los no activos a nil y sólo a 1 el que esté activo.
Saludos y dime si funciona
No lo he probado todavÃa pero supongo que si tiene que funcionar en ese
caso.
Siguiendo con el callback, habÃa pensado ésto:
class Destacado < ActiveRecord::Base
def before_save
begin
@destacado=Destacado.find_by_activado(1)
rescue ActiveRecord::RecordNotFound
#No se graba, lanzar error en plantilla "Ya existe un
activado"
else
#Se graba
end
end
end
pero no se qué sintaxis poner en cada caso, me podeis ayudar?
Cierto, se me habÃa pasado. Prueba:
class Person < ActiveRecord::Base
validates_uniqueness_of :activado, :allow_nil=true
…
end
Asà creo que los que están a nil los acepta como válidos. Por tanto, pon
los no activos a nil y sólo a 1 el que esté activo.
Saludos y dime si funciona
Creo que lo que habrÃa que hacer es lanzar una excepción para que no
grabe:
class Destacado < ActiveRecord::Base
def before_save
throw Exception.new if Destacado.find_by_activado(1)
end
end
y fuera pones el begin/rescue/else para redirigir o no.