counter_cache 实现的问题

发布于 2024-10-04 12:53:07 字数 590 浏览 0 评论 0原文

我的耙子要中止了! ... posts_count 被标记为只读错误。

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

users has_many posts.

posts belongs_to :user, :counter_cache => true

我有一个迁移,它将 posts_count 列添加到用户表中,然后计算并记录每个用户的当前帖子数。

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

当我运行迁移时出现错误。当然,这是非常明确的,如果我从帖子模型中删除 :counter_cache 声明,例如

belongs_to :user

迁移运行正常。显然,这没有意义,因为你无法真正以这种方式实现它。我缺少什么?

I'm getting 'rake aborted! ... posts_count is marked readonly' errors.

I have two models: user and post.

users has_many posts.

posts belongs_to :user, :counter_cache => true

I have a migration which adds the posts_count column to the users table and then calculates and records the current number of posts per user.

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

when I run the migration I get the error. This is pretty clear-cut, of course and if I remove the :counter_cache declaration from the posts model, e.g.

belongs_to :user

the migration runs fine. This obviously, does not make sense because you couldn't really implement it this way. What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

善良天后 2024-10-11 12:53:07

您应该使用 User.reset_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

You should be using User.reset_counters to do this. Additionally, I would recommend using find_each instead of each because it will iterate the collection in batches instead of all at once.

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
狼性发作 2024-10-11 12:53:07

好的,文档说明:

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

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

快速而肮脏的解决方案是从模型中删除 counter_cache 声明,运行迁移(以便将所需的列添加到数据库并用当前的帖子计数填充它),然后将 counter_cache 声明重新添加到模型。应该可以工作,但很麻烦,并且在迁移过程中需要手动干预 - 这不是一个好主意。

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

OK, the documentation states:

Counter cache columns are added to the
containing model’s list of read-only
attributes through attr_readonly.

I think this is what happens: you declare the counter in the model's definition, thus rendering the "posts_count" attribute read-only. Then, in the migration, you attempt to update it directly, resulting in the error you mention.

The quick-and-dirty solution is to remove the counter_cache declaration from the model, run the migration (in order to add the required column to the database AND populate it with the current post counts), and then re-add the counter_cache declaration to the model. Should work but is nasty and requires manual intervention during the migration - not a good idea.

I found this blog post which suggests altering the model's list of read-only attributes during the migration, it's a bit oudated but you might want to give it a try.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文