Make less sql queries when loading comments (#1197)

This commit is contained in:
Anna Buyanova 2018-11-26 18:51:38 +03:00 committed by Ben Halpern
parent 73b1616bb5
commit c1eb30e02a
8 changed files with 95 additions and 33 deletions

View file

@ -10,4 +10,18 @@ module CommentsHelper
def comment_user_id_unless_deleted(comment)
comment.deleted ? 0 : comment.user_id
end
def tree_for(comment, commentable)
nested_comments(tree: comment.subtree.includes(:user).arrange, commentable: commentable, is_view_root: true)
end
private
def nested_comments(tree:, commentable:, is_view_root: false)
tree.map do |comment, sub_comments|
render("comments/comment", comment: comment, commentable: commentable,
is_view_root: is_view_root, is_childless: sub_comments.empty?,
subtree_html: nested_comments(tree: sub_comments, commentable: commentable))
end.join.html_safe
end
end

View file

@ -187,12 +187,9 @@
commentable: @article,
commentable_type: "Article" %>
<div class="comment-trees" id="comment-trees-container">
<% Comment.rooted_on(@article.id,"Article").order("score DESC").limit(@comments_to_show_count).each_with_index do |comment, i| %>
<% Comment.rooted_on(@article.id, "Article").order("score DESC").limit(@comments_to_show_count).each_with_index do |comment, i| %>
<% cache ["comment_root_#{user_signed_in?}", comment] do %>
<%= render("/comments/comment",
comment:comment,
commentable: @article,
is_view_root: true) %>
<%= tree_for(comment, @article) %>
<% end %>
<% end %>
</div>

View file

@ -76,7 +76,7 @@
<a href="<%=commentable.path%>/comments/<%= comment.id_code_generated %>/edit" class="edit-butt" rel="nofollow">EDIT</a>
</span>
<% end %>
<% if comment.depth < 2 || comment.is_childless? %>
<% if comment.depth < 2 || is_childless %>
<a href="#<%=commentable.path%>/comments/new/<%= comment.id_code_generated %>" class="toggle-reply-form" rel="nofollow">REPLY</a>
<% else %>
<a href="#<%=commentable.path%>/comments/new/<%= comment.id_code_generated %>" class="toggle-reply-form thread-indication" rel="nofollow">THREAD</a>
@ -84,8 +84,6 @@
</div>
</div>
<% end %>
<% comment.children.includes(:user, :commentable).order("score DESC").each do |child| %>
<%= render("comments/comment", comment:child, commentable:comment.commentable, is_view_root:false) %>
<% end %>
<%= subtree_html %>
</div>
<% end %>

View file

@ -75,7 +75,6 @@
<% end %>
<a href="<%=@commentable.path%>/comments">VIEW FULL DISCUSSION</a>
</span>
</div>
<% else %>
<%= render "form",
@ -87,13 +86,13 @@
<% if @root_comment.present? %>
<div class="root-comment">
<% cache ["comment_root-view-root_#{user_signed_in?}", @root_comment] do %>
<%= render("comment", comment:@root_comment, commentable:@commentable, is_view_root: true) %>
<%= tree_for(@root_comment, @commentable) %>
<% end %>
</div>
<% else %>
<% Comment.rooted_on(@commentable.id,@commentable_type).order("score DESC").each do |comment| %>
<% Comment.rooted_on(@commentable.id, @commentable_type).order("score DESC").each do |comment| %>
<% cache ["comment_root_#{user_signed_in?}", comment] do %>
<%= render("comment", comment:comment, commentable:@commentable, is_view_root: false) %>
<%= tree_for(comment, @commentable) %>
<% end %>
<% end %>
<% end %>

View file

@ -109,10 +109,7 @@
<div class="comment-trees" id="comment-trees-container">
<% Comment.rooted_on(@episode.id,"PodcastEpisode").order("score DESC").limit(12).each do |comment| %>
<% cache ["comment_root_#{user_signed_in?}", comment] do %>
<%= render("/comments/comment",
comment:comment,
commentable: @episode,
is_view_root: true) %>
<%= tree_for(comment, @episode) %>
<% end %>
<% end %>
</div>

View file

@ -0,0 +1,33 @@
require "rails_helper"
describe "Views an article" do
let(:user) { create(:user) }
let(:dir) { "../support/fixtures/sample_article.txt" }
let(:template) { File.read(File.join(File.dirname(__FILE__), dir)) }
let(:article) do
create(:article,
user_id: user.id,
body_markdown: template.gsub("false", "true"),
body_html: "")
end
let!(:comment) { create(:comment, commentable: article) }
let!(:child_comment) { create(:comment, parent: comment, commentable: article) }
before do
create(:comment, commentable: article)
sign_in user
end
it "shows all comments" do
visit "#{article.path}/comments"
expect(page).to have_selector(".single-comment-node", visible: true, count: 3)
end
it "shows a thread" do
visit "#{article.path}/comments/#{comment.id}"
expect(page).to have_selector(".single-comment-node", visible: true, count: 2)
expect(page).to have_selector(".comment-deep-0#comment-node-#{comment.id}", visible: true, count: 1)
expect(page).to have_selector(".comment-deep-1#comment-node-#{child_comment.id}", visible: true, count: 1)
end
end

View file

@ -0,0 +1,28 @@
require "rails_helper"
describe "Views an article" do
let(:user) { create(:user) }
let(:dir) { "../support/fixtures/sample_article.txt" }
let(:template) { File.read(File.join(File.dirname(__FILE__), dir)) }
let(:article) do
create(:article,
user_id: user.id,
body_markdown: template.gsub("false", "true"),
body_html: "")
end
before do
sign_in user
end
it "shows an article" do
visit "/#{user.username}/#{article.slug}"
expect(page).to have_content(article.title)
end
it "shows comments", js: true, retry: 3 do
create_list(:comment, 3, commentable: article)
visit "/#{user.username}/#{article.slug}"
expect(page).to have_selector(".single-comment-node", visible: true, count: 3)
end
end

View file

@ -4,32 +4,28 @@ describe "User visits podcast show page" do
let(:podcast) { create(:podcast) }
let(:podcast_episode) { create(:podcast_episode, podcast_id: podcast.id) }
let(:user) { create(:user) }
let(:comment) do
create(:comment, user_id: user.id,
commentable_id: podcast_episode.id,
commentable_type: "Article")
end
let(:comment2) do
create(:comment,
user_id: user.id,
commentable_id: article.id,
parent_id: podcast_episode.id,
commentable_type: "Article")
end
it "they see the content of the hero" do
visit podcast_episode.path.to_s
expect(page).to have_text(podcast_episode.title)
expect(page).to have_css ".record"
end
it "see the new comment box on the page" do
visit podcast_episode.path.to_s
expect(page).to have_css "form#new_comment"
expect(find("#comment_commentable_type", visible: false).value).to eq("PodcastEpisode")
expect(find("#comment_commentable_id", visible: false).value).to eq(podcast_episode.id.to_s)
end
# scenario 'see comments on the page' do
# visit "#{podcast_episode.path}"
# expect(page).to have_css '#comment-node-'+comment.id
# end
context "when there're existing comments" do
let(:comment) { create(:comment, user_id: user.id, commentable: podcast_episode) }
let!(:comment2) { create(:comment, user_id: user.id, commentable: podcast_episode, parent: comment) }
it "sees the comments" do
visit podcast_episode.path.to_s
expect(page).to have_selector(".comment-deep-0#comment-node-#{comment.id}", visible: true, count: 1)
expect(page).to have_selector(".comment-deep-1#comment-node-#{comment2.id}", visible: true, count: 1)
end
end
end