2012-07-16 73 views
31

我有一个图片模型,其中包含一个视图计数(整数)的变量。 每次有人查看图片对象时,查看计数都会加1。。增量vs + = 1

在完成这一操作,是什么

@picture.view_count += 1 
    @picture.save 

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

另外,如果我使用的增量,是.save必要区别?

+1

应该不是语法是'@ picture.increment(:VIEW_COUNT,1)'? – 2013-04-10 14:03:16

+0

注意并发性!在这种情况下,您的两种解决方案都不安全!想象一下,两个用户同时运行代码。两者都使用相同的'view_count'值。然后第二个用户在保存时覆盖第一个用户的值,最终计数比预期的少一个。 你应该使用'increment_counter'来避免这种情况。 – 2016-10-19 10:39:29

回答

45

increment的来源位于下方,如果nil将属性初始化为零并添加通过的值(默认值为1),则不会保存,因此.save仍然是必需的。

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

或者你可以使用'increment!'方法,如果你不想手动保存 – 2012-07-16 06:40:19

+2

这是有点过时了,新方法是increment_counter – timroman 2014-06-28 04:00:52

+0

你认为这个增量的东西可以与关系范围?发布has_many图像,图像模型具有需要递增的位置属性 – Ben 2014-12-06 15:33:54

4

您应该使用counter_cache。 counter_cache帮助你自动增加记录数量。

class Picture < ActiveRecord::Base 
    has_many :views 
end 

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

图片表需要柱名views_count,或者您可以使用自己的名字此列,例如:

belongs_to :picture, counter_cache: :number_of_views 

但我建议你使用默认名称counter_cache列是views_count 。

+0

that' d需要一个模型,因此一个表?或者它可能被“抽象”? – Ben 2014-12-06 15:34:19

20

在这种情况下,我经常使用counter_cacheincrement_counter

这样的:

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

这种方式更简单,比自制方法快。

顺便说一句,ActiveRecord :: CounterCache也有decrement_counter

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

+2

这是最好的答案,因为它考虑了并发性。 – 2016-10-19 10:40:30