Duda callback

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 :wink:

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 :slight_smile:

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 :slight_smile:

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.