1

好的..我希望我在做一些愚蠢的事情(通常是这种情况)。我一直在嗡嗡作响,将缓存计数器添加到我现有的项目中,当所有突然的 reset_counters 几乎所有事情都失败时。当一切正常时,我检查了一个旧副本,但它仍然失败,所以我开始了一个全新的演示项目。

我认为这是我的错误,因为它突然停止工作......而且我没有看到其他人有类似的问题。我正在使用 ruby​​ 1.9.3-p392 和 rails 3.2.12。

柜台本身既适用于现有项目,也适用于新项目。你只是不能使用reset_counters。

所以这是一个全新项目的问题:

class Post < ActiveRecord::Base
  attr_accessible :name
  has_many :comments
end


class Comment < ActiveRecord::Base
  attr_accessible :name
  belongs_to :post, :counter_cache => true
end

在这里我们可以看到计数器的增量:

irb(main):073:0* post = Post.create(:name => 'i am a post')
   (0.3ms)  BEGIN
  SQL (0.4ms)  INSERT INTO `posts` (`comments_count`, `created_at`, `name`, `updated_at`) VALUES (0, '2013-03-14 19:56:53', 'i am a post', '2013-03-14 19:56:53')
   (0.5ms)  COMMIT
=> #<Post id: 3, name: "i am a post", created_at: "2013-03-14 19:56:53", updated_at: "2013-03-14 19:56:53", comments_count: 0>
irb(main):074:0> post.comments << Comment.new(:name => 'i am a comment')
   (0.2ms)  BEGIN
  SQL (0.3ms)  INSERT INTO `comments` (`created_at`, `name`, `post_id`, `updated_at`) VALUES ('2013-03-14 19:57:18', 'i am a comment', 3, '2013-03-14 19:57:18')
  Post Load (0.3ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 3 LIMIT 1
  SQL (0.3ms)  UPDATE `posts` SET `comments_count` = COALESCE(`comments_count`, 0) + 1 WHERE `posts`.`id` = 3
   (0.4ms)  COMMIT
  Comment Load (0.2ms)  SELECT `comments`.* FROM `comments` WHERE `comments`.`post_id` = 3
=> [#<Comment id: 3, name: "i am a comment", post_id: 3, created_at: "2013-03-14 19:57:18", updated_at: "2013-03-14 19:57:18">]
irb(main):075:0> post = Post.find(3)
  Post Load (0.5ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 3 LIMIT 1
=> #<Post id: 3, name: "i am a post", created_at: "2013-03-14 19:56:53", updated_at: "2013-03-14 19:56:53", comments_count: 1>

运行我得到的代码:

irb(main):001:0> Post.reset_counters(1,:comments_count)
  Post Load (0.5ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 1 LIMIT 1
NoMethodError: undefined method `options' for nil:NilClass
    from /Users/charles/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/activerecord-3.2.12/lib/active_record/counter_cache.rb:22:in `block in reset_counters'
    from /Users/charles/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/activerecord-3.2.12/lib/active_record/counter_cache.rb:19:in `each'
    from /Users/charles/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/activerecord-3.2.12/lib/active_record/counter_cache.rb:19:in `reset_counters'
    from (irb):1
    from /Users/charles/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/railties-3.2.12/lib/rails/commands/console.rb:47:in `start'
    from /Users/charles/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/railties-3.2.12/lib/rails/commands/console.rb:8:in `start'
    from /Users/charles/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/railties-3.2.12/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'
4

1 回答 1

3

你几乎完全正确。尽管中的参数reset_counters应该是对象名称,而不是列名称。因此,在您的情况下,您想要:

1.9.3-p392 :005 > Post.reset_counters(1, :comments)
  Post Load (0.3ms)  SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1  [["id", 1]]
   (0.1ms)  SELECT COUNT(*) FROM "comments" WHERE "comments"."post_id" = 1
   (2.3ms)  UPDATE "posts" SET "comments_count" = 1 WHERE "posts"."id" = 1
 => true 
于 2013-03-15T12:41:33.723 回答