44

レーキが中止されました!...posts_countは読み取り専用のエラーとしてマークされています。

ユーザーと投稿の2つのモデルがあります。

users has_many posts.

posts belongs_to :user, :counter_cache => true

私はposts_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

移行を実行すると、エラーが発生します。もちろん、これはかなり明確です。投稿モデルから:counter_cache宣言を削除すると、たとえば

belongs_to :user

移行は正常に実行されます。この方法で実際に実装することはできなかったため、これは明らかに意味がありません。私は何が欠けていますか?

4

2 に答える 2

98

これを行うために使用User.reset_countersする必要があります。さらに、find_each代わりに ofを使用することをお勧めします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
于 2010-11-28T05:14:05.123 に答える
3

OK、ドキュメントには次のように記載されています。

カウンター キャッシュ列は、attr_readonly を介して、含まれているモデルの読み取り専用属性のリストに追加されます。

モデルの定義でカウンターを宣言すると、「posts_count」属性が読み取り専用になります。次に、移行で直接更新しようとすると、言及したエラーが発生します。

手っ取り早い解決策は、モデルから counter_cache 宣言を削除し、移行を実行して (データベースに必要な列を追加し、現在の投稿カウントを入力するため)、次に counter_cache 宣言を再度追加することです。モデル。動作するはずですが、厄介であり、移行中に手動で介入する必要があります - 良い考えではありません.

移行中にモデルの読み取り専用属性のリストを変更することを提案するこのブログ投稿を見つけました。これは少し古くなっていますが、試してみることをお勧めします。

于 2010-11-28T04:46:20.637 に答える