ruby-on-rails - 为什么 << 关联时 counter_cache 列不增加?

标签 ruby-on-rails associations counter-cache

假设我有以下模型:

class Location < Active::Record
  has_many :storables, foreign_key: :bin_id
  # ...
end

class Storable < Active::Record
  belongs_to :bin, class_name: :Location, counter_cache: true
  # ...
end

当我运行以下规范时,counter_cache 没有正确递增。方法 #1#2 按预期工作,但不是 #3。给了什么?

describe "location storables" do
  specify "adding a storable increments the counter cache" do
    l = Location.create
    l.storables_count.should == 0 #=> PASSES

    # method 1
    s = Storable.create(bin: l)
    l.reload
    l.storables_count.should == 1 #=> PASSES

    # method 2
    l.storables.create
    l.reload
    l.storables_count.should == 2 #=> PASSES

    # method 3
    l.storables << Storable.create
    l.reload
    l.storables_count.should == 3 #=> FAILS, got 2 not 3
  end
end

我真的对counter_cache half working感到困惑。我也找不到配置问题。

在此项目上使用 Rails 3.2.12

更新

升级到 rails 4 没有帮助。此外,如果我将方法 #3 更改为以下内容,则测试通过:

# method 3
l.storables << Storable.create
puts "proxy    : #{l.storables.count}" #=> 3
puts "relation : #{Storable.count}"    #=> 3
puts "cache    : #{l.storables_count}"    #=> 2

Location.reset_counters(l.id, :storables) # corrects cache

l.reload
l.storables_count.should == 3 #=> PASSES

为什么这不是自动发生的?

最佳答案

一方面,我认为写类似l.storables << Storable.create 的东西不合适。 .

通过编写此代码,会发生两件事:

  1. Storable.create使用 location_id 创建一个新的 Storable 对象无

  2. l.storables <<更新创建的对象,将 location_id 设置为 l.id ,并以某种方式忘记更新计数器缓存。

这可能是 ActiveRecord 的错,因为它应该更聪明,但您实际上执行了两个 SQL(insert into storable & update storable set location_id = something)只是为了插入一个新的可存储记录。无论如何,这是个坏主意,如果你对 location_id 有外键约束,第一次插入甚至会失败。

所以使用l.storables << Storable.new相反

附注:与l.storables << Storable.create , 因为返回值为 Storable.create不是新记录,有点难l决定做什么。在某些情况下,它需要增加自己的计数器缓存,在其他情况下,它需要增加自己的计数器缓存并减少其他人的计数器缓存,或者它可能什么都不做。

关于ruby-on-rails - 为什么 << 关联时 counter_cache 列不增加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17583163/

相关文章:

ruby-on-rails - 无法使 Resque 工作

ruby-on-rails - 从 Controller (Rails 3)中的 application.rb 访问配置

ruby-on-rails - 如何捕获/解决 ActiveRecord :RecordInvalid exception caused when I save a built assocation

ruby-on-rails - 如何知道模型何时被 :dependent => :destroy in rails? 自动销毁

mysql - 如何优化 ORDER 条件以防止文件排序?

ruby-on-rails - 捆绑 geoip-c - 给出错误 "you must have geoip c library installed"

ruby-on-rails - 如何在 Rails Active Record 中关闭自动增量

php - CakePHP (2.4) 深层关系

ruby-on-rails - 作用域关联上的 Rails 中的 counter_cache

ruby-on-rails - Rails 4计数器缓存不同步