我遵循此tutorial在我的网站上进行了完全相同的评论,现在我想显示该文章的评论数,但我只能获得该文章的答案数而不包括该数字评论的答案。
我不想在带有引用文章ID的评论模型中添加一列,因为我的网站已经在线,并且所有旧帖子将有0条评论,因为他们将没有此新列。
我该怎么办?我认为这与belong_to
有关,但是在官方文档中我找不到它。
我的model/comment.rb
class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true
has_many :comments, as: :commentable
serialize :report, Array
validates :commenter, presence: true, length: { in: 1..500 }
end
我的model/article.rb
class Article < ApplicationRecord
include BCrypt
serialize :view, Array
serialize :upvote, Array
serialize :report, Array
has_many :comments, as: :commentable, dependent: :destroy
validates :title, presence: true, length: { in: 1..60 }
validates :content, presence: true
has_secure_password
end
编辑:
也许我可以在帮助器中执行一个循环,该循环将计算评论的每个评论,但是我不知道如何像Article.find(my_article_id).comments.each do
这样循环,然后我不知道该怎么做。这样做,那么也许我应该喜欢Comment.comments.each do
吗?
我本来想做一个递归方法,但是我总是努力做一个递归方法
EDIT2:
schema/article
create_table "articles", force: :cascade do |t|
t.string "title"
t.string "author"
t.string "author_ip"
t.string "password_digest"
t.text "content"
t.string "upvote"
t.integer "upvote_count", default: 0
t.string "view"
t.integer "view_count", default: 0
t.string "report"
t.integer "report_count", default: 0
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "activate", default: true
t.integer "comments_count", default: 0, null: false
end
schema/comment
create_table "comments", force: :cascade do |t|
t.text "commenter"
t.string "author"
t.string "author_ip"
t.string "date"
t.integer "commentable_id"
t.string "commentable_type"
t.string "report"
t.integer "report_count", default: 0
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "article_id"
end
EDIT3:
comment migration
class AddCommentsCountToComments < ActiveRecord::Migration[5.2]
def change
add_column :comments, :comments_count, :integer, default: 0, null: false
Comment.reset_column_information # to reset cached values
Comment.find_each do |comment|
comment.update(comments_count: comment.comments.count) # updating old articles comments_counter
end
end
end
答案 0 :(得分:0)
您可以这样获得评论和子评论的数量:
article.comments.sum { |comment| 1 + comment.comments.count }
但是,这将对您的文章的每个父注释执行一个查询,这并不理想。
执行此操作的其他方式:
article_id
,并在迁移时填充当前评论答案 1 :(得分:0)
您可以始终使用article.comments.size
,但这并不理想,因为它将始终对数据库进行查询。
另一种方法是在comments_count
模型中添加计数器缓存articles
列,也可以为同一迁移中在计数器缓存之前创建的任何商品更新comments_count
。>
您可以从添加迁移开始
def change
add_column :articles, :comments_count, :integer, default: 0, null: false
Article.reset_column_information # to reset cached values
Article.find_each do |article|
article.update(comments_count: article.comments.count) # updating old articles comments_count
end
end
现在,如果您运行迁移并在控制台中检查了在迁移之前撰写的文章,那么comments_count
应该反映出文章的评论数。
现在,最后一步是向counter_cache
模型添加comment
选项。
counter_cache
选项可确保无论何时添加或删除注释,comments_count
列中的数字始终会更新。
belongs_to :commentable, polymorphic: true, counter_cache: true
现在要获取缓存的值,您可以使用:
article.comments.size
,就像您在has_many关联上使用counter_cache
一样,size
将直接使用缓存的计数,根本不会进行任何查询。article.comments_count
。类似地,要缓存comment.comments.count
或comment.comments_count
,还需要为comments
表添加另一个计数器缓存。
要获取所有注释,包括针对特定article
的嵌套注释,您需要获取文章注释计数(外部注释)+每个注释注释计数。
article.comments_count + article.comments.sum(:comments_count)
要干燥代码(如果需要重用),可以按如下方式在article
模型内添加实例方法:
def comments_count_including_nested
comments_count + comments.sum(:comments_count)
end
然后您可以致电article.comments_count_including_nested