2012-07-16 7 views
31

Tengo un modelo de imagen que contiene una variable para un recuento de vista (entero). El recuento de vistas se incrementa en +1 cada vez que alguien ve el objeto Imagen..incremento vs + = 1

En conseguir este hecho, ¿cuál es la diferencia entre

@picture.view_count += 1 
    @picture.save 

y

@picture.increment(:view_count, by = 1) 

también si uso mínimo de la subasta, es necesario .save?

+1

¿No debería ser la sintaxis '@ picture.increment (: view_count, 1)'? –

+0

¡Tenga en cuenta la concurrencia! ¡Sus dos soluciones no son seguras en este caso! Imagina que dos usuarios ejecutan el código al mismo tiempo. Ambos funcionan con el mismo valor 'view_count'. Luego, el segundo usuario sobrescribe el valor del primer usuario al guardar y el conteo final es uno menos de lo esperado. Debe usar 'increment_counter' para evitar esto. –

Respuesta

45

La fuente de increment está debajo, que inicializa el atributo a cero si nulo y agrega el valor pasado como por (predeterminado es 1), no guarda, por lo que .save sigue siendo necesario.

def increment(attribute, by = 1) 
    self[attribute] ||= 0 
    self[attribute] += by 
    self 
end 
+24

o puede usar el método 'increment!' Si no quiere guardarlo manualmente –

+2

Esto es un poco anticuado, el nuevo método es increment_counter – timroman

+0

¿cree que este incremento podría tener un alcance con una relación? publicar has_many images, el modelo de imagen tiene un atributo de posición que requeriría ser incrementado – Ben

4

Debe usar counter_cache. counter_cache te ayuda a incrementar el número de registros automáticamente.

class Picture < ActiveRecord::Base 
    has_many :views 
end 

class View < ActiveRecord::Base 
    belongs_to :picture, counter_cache: true 
end 

imágenes tabla necesita columna con el nombre views_count, o puede utilizar su propio nombre para esta columna, por ejemplo:

belongs_to :picture, counter_cache: :number_of_views 

pero recomiendo que use el nombre por defecto para counter_cache columna que es views_count .

+0

eso ' d requiere un modelo, por lo tanto, una tabla? o podría ser "abstraído"? – Ben

20

A menudo uso counter_cache y increment_counter en ese caso.

así:

Picture.increment_counter(:view_count, @picture.id) 

De esta manera es más sencillo y rápido que el método de fabricación propia.

Por cierto, ActiveRecord :: CounterCache también tiene decrement_counter.

http://api.rubyonrails.org/classes/ActiveRecord/CounterCache/ClassMethods.html

+2

Esta es la mejor respuesta, porque se encarga de la concurrencia. –