如何在更新模型时更新counter_cache?

Mar*_*rov 6 ruby-on-rails

我有一个简单的关系:

class Item
  belongs_to :container, :counter_cache => true
end

class Container
  has_many :items
end
Run Code Online (Sandbox Code Playgroud)

假设我有两个容器.我创建一个项目并将其与第一个容器相关联.柜台增加了.

然后我决定将它与其他容器相关联.如何更新两个容器的items_count列?

我在http://railsforum.com/viewtopic.php?id=39285找到了一个可能的解决方案..但是我是初学者,我不明白.这是唯一的方法吗?

fl0*_*00r 3

它应该自动工作。当您更新时,items.container_id它将减少旧容器的计数器并增加新容器的计数器。但如果它不起作用——那就奇怪了。你可以尝试这个回调:

class Item
  belongs_to :container, :counter_cache => true
  before_save :update_counters

  private
  def update_counters
    new_container = Container.find self.container_id
    old_container = Container.find self.container_id_was
    new_container.increament(:items_count)
    old_container.decreament(:items_count)
  end
end
Run Code Online (Sandbox Code Playgroud)

UPD

演示本机行为:

container1 = Container.create :title => "container 1"
#=> #<Container title: "container 1", :items_count: nil>
container2 = Container.create :title => "container 2"
#=> #<Container title: "container 2", :items_count: nil>
item = container1.items.create(:title => "item 1")
Container.first
#=> #<Container title: "container 1", :items_count: 1>
Container.last
#=> #<Container title: "container 1", :items_count: nil>
item.container = Container.last
item.save
Container.first
#=> #<Container title: "container 1", :items_count: 0>
Container.last
#=> #<Container title: "container 1", :items_count: 1>
Run Code Online (Sandbox Code Playgroud)

所以它应该可以在没有任何黑客攻击的情况下工作。从盒子里。