Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/53.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 计数器缓存实现存在问题_Ruby On Rails_Counter Cache - Fatal编程技术网

Ruby on rails 计数器缓存实现存在问题

Ruby on rails 计数器缓存实现存在问题,ruby-on-rails,counter-cache,Ruby On Rails,Counter Cache,我要把“耙子流产”。。。posts\U计数标记为只读错误 我有两个模型:用户模型和帖子模型 users has_many posts. posts belongs_to :user, :counter_cache => true 我有一个迁移,它将posts\u count列添加到users表中,然后计算并记录每个用户当前的帖子数量 self.up add_column :users, :posts_count, :integer, :default => 0 User

我要把“耙子流产”。。。posts\U计数标记为只读错误

我有两个模型:用户模型和帖子模型

users has_many posts.

posts belongs_to :user, :counter_cache => true
我有一个迁移,它将posts\u count列添加到users表中,然后计算并记录每个用户当前的帖子数量

self.up
  add_column :users, :posts_count, :integer, :default => 0

  User.reset_column_information
  User.all.each do |u|
    u.update_attribute( :posts_count, u.posts.count)
  end
end
当我运行迁移时,我得到了错误。当然,这是非常明确的,如果我从posts模型中删除:counter_cache声明,例如

belongs_to :user

迁移运行良好。这显然是没有意义的,因为您无法以这种方式真正实现它。我遗漏了什么?

好的,文档说明:

计数器缓存列将添加到 包含模型的只读列表 属性通过属性只读

我认为情况就是这样:在模型的定义中声明计数器,从而将“posts\u count”属性呈现为只读。然后,在迁移过程中,您试图直接更新它,导致您提到的错误

快速而肮脏的解决方案是从模型中删除计数器缓存声明,运行迁移(以便将所需的列添加到数据库并用当前的post计数填充),然后将计数器缓存声明重新添加到模型中。应该可以工作,但是很糟糕,在迁移过程中需要人工干预——这不是一个好主意


我发现这建议在迁移期间更改模型的只读属性列表,这有点过时,但您可能想尝试一下。

您应该使用
User.reset\u counters
来执行此操作。此外,我建议使用
find_each
而不是
each
,因为它将成批迭代集合,而不是一次迭代所有集合

self.up
  add_column :users, :posts_count, :integer, :default => 0

  User.reset_column_information
  User.find_each do |u|
    User.reset_counters u.id, :posts
  end
end

我感谢你的帮助。我正在使用你建议的变通方法,但正如你所同意的,这不是一个让产品投入生产的好方法。同样感谢你的博客文章,但这种黑客行为似乎不再有效(我目前正在使用rails 3.0.1)。我可能只需要滚动自己的缓存计数器并在应用程序中维护它们。那篇博客文章有误导性或过时。看,这是我的问题
counter_cache:true
设置在后台执行一些
attr_readonly
magic幕后操作并阻止我的迁移这种方式在尝试在像heroku这样的远程存储库上执行时会带来问题。上传一个版本,关闭countercache,然后迁移,然后上传一个verson,实现countercache?似乎首选的方法是:“User.reset\u counters u.id,:posts\u count”。请参阅上面的轻微更正(无法再编辑该注释):“User.reset_counters u.id,:posts”@Mike Fischer很好,看起来
reset_counters
使用的SQL调用更少。@gwho我在
4-1-stable
master
中都没有看到任何关于这两种方法的弃用通知。你怎么会这么想@如果代码移动位置,gwho apidock会调用任何“不推荐的”。我通常避免那个网站,它经常像那样令人困惑。