我已将forum_posts_count
和forum_threads_count
列添加到论坛表格中。 forum_posts_count
工作得很好。 Forum has_many :forum_threads
已重置为“0”,而不是显示在添加计数器缓存列之前创建的所有论坛帖子。关系是:Forum has_many :forum_posts, through: :forum_threads
,ForumThreads has_many:forum_posts和has_many through:
。
我后来发现我不能使用after_create
关系的counter_cache。所以我写了一些私有方法来添加after_destroy
/ class AddCountersToForumsTableAgain < ActiveRecord::Migration
def self.up
change_table :forums do |t|
t.integer :forum_threads_count, :forum_posts_count, default: 0
end
Forum.reset_column_information
Forum.all.pluck(:id).each do |id|
Forum.reset_counters(id, :forum_posts)
Forum.reset_counters(id, :forum_threads)
end
end
def self.down
change_table :forums do |t|
t.remove :forum_threads_count, :forum_posts_count
end
end
end
调用来递增/递减计数器。计数器工作,只是它仍然没有考虑在将这些列添加到论坛表之前创建的所有论坛帖子。我觉得编写迁移的方式有点不对劲。请提前帮助并表示感谢。我感谢网站上的所有人帮助他们。
“... add_counters_to_forums_table.rb”(迁移文件)
class Forum < ActiveRecord::Base
has_many :forum_threads, -> { order ('updated_at DESC') }, dependent: :destroy
accepts_nested_attributes_for :forum_threads
has_many :forum_posts, through: :forum_threads
accepts_nested_attributes_for :forum_posts
end
模型/ forum.rb
class ForumThread < ActiveRecord::Base
belongs_to :user
belongs_to :forum, counter_cache: true
has_many :forum_posts, dependent: :destroy
accepts_nested_attributes_for :forum_posts
end
模型/ forum_thread.rb
class ForumPost < ActiveRecord::Base
belongs_to :forum_thread, touch: true
belongs_to :forum
belongs_to :user
after_create :increment_forum_posts_count
after_destroy :decrement_forum_posts_count
private
def increment_forum_posts_count
Forum.increment_counter( 'forum_posts_count', self.forum_thread.forum.id )
end
def decrement_forum_posts_count
Forum.decrement_counter( 'forum_posts_count', self.forum_thread.forum.id )
end
end
模型/ forum_post.rb
<%= render 'shared/page_title', title: "Forums" %>
<div class="col-md-10 col-md-offset-1">
<div class="actions">
<%= link_to "Create New Forum", new_forum_path, class: 'btn btn-primary' %>
<div class="pull-right">
<%= form_tag @forum_thread, method: :get do |f| %>
<%= text_field_tag :q, nil, class: 'form-control', placeholder: 'Search...' %>
<% end %>
</div>
</div>
# LIST FORUMS WITH THREADS AND POSTS COUNTER CACHE
<div class="list-group">
<% @forums.each do |forum| %>
<a href="<%= forum_forum_threads_path(forum.id, @forum_threads) %>" class="list-group-item">
<h3><%= forum.title %>
<div class="pull-right small">
<%= pluralize forum.forum_threads.size, 'thread' %> |
<%= pluralize forum.forum_posts.size, 'post' %>
</div>
</h3>
</a>
<% end %>
</div>
视图/论坛/ index.html.erb
{{1}}
答案 0 :(得分:1)
您可以在数据库中添加多个counter_cache列,看起来就像命名它们一样。为了让它们更新,您需要修改ForumThread和ForumPost模型,看起来有点像这样:
create_join_table
Rails Guides上有关于counter_cache的更多信息。还有RailsCast about counter_caches,
答案 1 :(得分:1)
您的迁移看起来很好;你可以改进它:
#db/migrate/add_counters_to_forums_table_....rb
class AddCountersToForumsTable < ActiveRecord::Migration
def self.up
change_table :forums do |t|
t.integer :forum_threads_count, :forum_posts_count, default: 0
end
Forum.all.pluck(:id).each do |id|
Forum.reset_counters(id, :forum_posts_count)
Forum.reset_counters(id, :forum_threads_count)
end
end
def self.down
change_table :forums do |t|
t.remove :forum_threads_count, :forum_posts_count
end
end
end
好参考:“updated Fiddle”
因为counter_cache
是在关联上定义的,只要您将其附加到不同的关联,就可以拥有任意数量的关联:
#app/models/forum.rb
class Forum < ActiveRecord::Base
has_many :forum_threads
has_many :forum_posts
end
#app/models/forum_thread.rb
class ForumThread < ActiveRecord::Base
belongs_to :forum, counter_cache: true
end
#app/models/forum_post.rb
class ForumPost < ActiveRecord::Base
belongs_to :forum, counter_cache: true
end
<强>更新强>
我认为问题在于你是Adding a Counter Cache to Existing Records:
#app/models/forum.rb
class Forum < ActiveRecord::Base
has_many :forum_threads
has_many :forum_posts, through: :forum_threads
delegate :forum_posts_count, to: :forum_threads
end
#app/models/forum_thread.rb
class ForumThread < ActiveRecord::Base
belongs_to :forum
has_many :forum_posts
end
#app/models/forum_post.rb
class ForumPost < ActiveRecord::Base
belongs_to :forum_thread, counter_cache: true
end
这是一个很好的参考:using counter_cache
on a has_many :through
association
如果您使用了我上面的代码(适用于has_many :through
),您最好进入counter_cache with has_many :through并更新各种ForumThread
,如下所示:
$ rails c
$ forums = Forum.all
$ forums.each do |forum|
$ forum.forum_posts.pluck(:id).each do |id|
$ ForumPost.reset_counters(id, :forum_posts_count)
$ end
$ end
此应为您正确重置计数器。
<强>更新强>
关于你的问题,我仍然觉得你可以使counter_cache与has_many :through
一起使用。我读了这个教程(Rails console),似乎确认你可以将counter_cache放在连接模型中。
虽然我们本身并没有这样做,但我认为没有理由不这样做。
在ForumPost
中,您确实不需要belongs_to :forum
- 这应仅适用于ForumTopic
。