0

我有一个标签模型,posts_count其中有一列用作标签具有的帖子数量的计数器缓存:

架构.rb:

 t.integer  "posts_count", :default => 0, :null => false

标记.rb:

 def decrement_tag_counter_cache
    Tag.decrement_counter(:posts_count, self.tag.id) if !post.published? || post.decrement_tag_counters? 
  end

post.rb:

  after_save :increment_decrement_tag_counters # covers :save, :create, :update methods

  def increment_tag_counters? # if status changes and the previous status wasn't "Published"
    status_changed? && changed_attributes["status"] != "Published"
  end

  def decrement_tag_counters? # if status changes and the previous status was "Published"
    status_changed? && changed_attributes["status"] == "Published"
  end

  def increment_decrement_tag_counters
    if published? && increment_tag_counters?
      taggings.each { |tagging| tagging.increment_tag_counter_cache }
    elsif decrement_tag_counters?
      taggings.each { |tagging| tagging.decrement_tag_counter_cache }
    end
  end

现在的问题是,有时该decrement_tag_counter_cache方法会posts_count变为负数(例如-1)。

有没有办法告诉 Rails:使最小值为posts_count0?因此,如果当前值为 0 并且计数器递减,posts_count仍将保持为 0?我可以做的另一件事是防止decrement_counter设置负值。那可能吗?

(这不应该作为验证,而是作为默认行为,因为我不希望出现错误。)

4

3 回答 3

1

您可以对 posts_count 进行验证,如下所示

validates :posts_count, :numericality => { :greater_than_or_equal_to => 0 }

或者你可以做这样的事情

before_save :set_posts_count

def set_posts_count
  posts_count = 0 if posts_count < 0
end
于 2012-12-29T09:49:29.133 回答
0

问题可能会出现,因为据我所知,这种方法没有初始化模型实例,所以它发送一个像这样的直接 sql 查询:

UPDATE "Tags" SET "posts_counter" = COALESCE("posts_counter", 0) - 1 WHERE "Tags"."id" = 5

如果是这样,我不知道如何解决这个问题,可能你可以用锁初始化模型实例然后递减计数器,但是锁有它的缺点

于 2014-09-11T04:05:27.920 回答
0

你可以做这样的事情

[posts_count, 0].max
于 2016-05-25T21:45:20.070 回答