tutorial rails que ejemplos descargar curso caracteristicas ruby-on-rails ruby-on-rails-3 activerecord ruby-on-rails-3.2 rails-activerecord

ruby-on-rails - que - ruby on rails tutorial



Cómo guardar un modelo sin ejecutar devoluciones de llamada en Rails (7)

Necesito calcular valores al guardar un modelo en Rails. Así que llamo a calculate_averages como una devolución de llamada para una clase de Survey :

before_save :calculate_averages

Sin embargo, ocasionalmente (e inicialmente tengo 10k registros que necesitan esta operación) necesito actualizar manualmente todos los promedios para cada registro. No hay problema, tengo un código como el siguiente:

Survey.all.each do |survey| survey.some_average = (survey.some_value + survey.some_other_value) / 2.to_f #and some more averages... survey.save! end

Incluso antes de ejecutar este código, me preocupa que los calculate_averages se llamen y se dupliquen, y probablemente incluso causen algunos problemas con la forma en que hago las cosas. Bien, entonces creo que, bueno, no haré nada y dejaré que calculate_averages y hagamos su trabajo. El problema es que, primero, ¿hay una manera de forzar la devolución de llamadas, incluso si usted no hizo cambios en el registro?

En segundo lugar, la forma en que se calculan los promedios es mucho más eficiente simplemente porque no permite que se realicen llamadas en absoluto y que se hagan los promedios de todo al mismo tiempo. ¿Es esto posible no permitir que se devuelvan llamadas?


Creo que lo que está pidiendo se puede lograr con ActiveSupport::Callbacks . Echa un vistazo a set_callback y skip_callback .

Para "forzar que se devuelvan las devoluciones de llamada, incluso si no ha realizado cambios en el registro", debe registrar la devolución de llamada en algún evento, por ejemplo save, validate etc.

set_callback :save, :before, :my_before_save_callback

Para omitir la before_save llamada before_save , harías:

Survey.skip_callback(:save, :before, :calculate_average).

Consulte el ActiveSupport::Callbacks en otras opciones compatibles, como las condiciones y los bloques, a set_callback y skip_callback .


Esperemos que esto es lo que estás buscando.

https://.com/a/6587546/2238259

Para su segundo problema, sospecho que sería mejor inspeccionar cuándo es necesario que ocurra este cálculo, sería mejor si pudiera manejarse por lotes en un momento específico donde el tráfico de red está en su punto más bajo.

EDIT: Woops. De hecho, encontré 2 enlaces pero perdí el primero, al parecer. Esperemos que lo tengas arreglado.



Para Rails 3 ActiveSupport::Callbacks te da el control necesario. Puede reset_callbacks en masa o usar skip_callback para deshabilitar juiciosamente de esta manera:

Vote.skip_callback(:save, :after, :add_points_to_user)

… Después de lo cual puede operar en instancias de Vote con :add_points_to_user inhibited


Para deshabilitar las devoluciones de llamada en masa use ...

Survey.skip_callback(:calculate_averages)

Entonces para habilitarlos ...

Survey.set_callback(:calculate_average)

Esto salta / establece para todas las instancias.


Si desea omitir devoluciones de llamada condicionalmente después de verificar cada encuesta, puede escribir su método personalizado.

Por ej.

  • Callback modificado

`

before_save :calculate_averages, if: Proc.new{ |survey| !survey.skip_callback }

`

  • Nuevo método de instancia

`

def skip_callback(value = false) @skip_callback = @skip_callback ? @skip_callback : value end

`

  • Script para actualizar encuestas-

`

Survey.all.each do |survey| survey.some_average = (survey.some_value + survey.some_other_value) / 2.to_f #and some more averages... survey.skip_callback(true) survey.save! end

`

Es un poco hack pero la esperanza funcionará para ti.


update_column es una función ActiveRecord que no ejecuta ninguna devolución de llamada y tampoco ejecuta la validación.