N + 1 の問題を回避するために、「bullet」という gem を使用しています。
私の以前のコードは
@communities = Community.scoped.page(params[:page]).order("created_at DESC")
次に、このエラーが発生していました
N+1 Query detected
Community => [:platform]
Add to your finder: :include => [:platform]
N+1 Query detected
Community => [:genre]
Add to your finder: :include => [:genre]
N+1 Query detected
Community => [:tags]
Add to your finder: :include => [:tags]
次に、70 を超える SQL を含むページを表示するのに約 650 ミリ秒かかりました。
なので、これに変更しました
@communities = Community.scoped.page(params[:page]).per(10).order("created_at DESC").includes(:platform, :genre, :tags)
現在、弾丸のアラートはなくなりましたが、750ms かかっており、まだ 70 以上の SQL があります。
何故ですか?
これは、ページを表示するのにかかった時間の結果です (w/rack-mini-profiler)
例えば、それぞれ約30msかかってcommunities/_community
いるcount
それぞれcommunities/_community
がこれら 2 つのヘルパーを呼び出します。ここに多数のSQLがある理由でしょうか?
def topic_button(community)
last_post = community.community_topics.order('last_active_at DESC').first
if last_post && last_post.last_active_at.today?
link_to sanitize( "Topics ("+ community.community_topics.count.to_s+")" , community_community_topics_path(community)
end
end
def uploader_button(community)
last_post = community.community_uploaders.order('last_active_at DESC').first
if last_post && last_post.last_active_at.today?
link_to sanitize("Chat ("+ community.community_uploaders.count.to_s+")" , community_community_uploaders_path(community)
end
end
アップデート
models/community.rb
paginates_per 10
controllers/communities_controller.rb
@communities = Community.scoped.page(params[:page]).order("created_at DESC")
/views/communities/index.html.erb
<span class='community'>
<% @communities.each do |community| %>
<%= render 'communities/community', :community => community %>
<% end %>
</span>
/views/communities/_community.html.erb
<div class="Box">
<div class="List">
<p class="name"><span><%= community.title %></span></p>
<%= community.community_name %>
<p class="img">
<% if community.community_icon? %>
<%= link_to image_tag(community.community_icon.url(:medium), :alt => community.title, :style => "width: 250px; height: 250px", :class => 'img-polaroid' ), community_path(community.community_name) %>
<% end %>
</p>
<div class="link">
<%= platform_search(community.platform.name, community.platform_id) %>
<%= genre_search(community.genre.name, community.genre_id) %>
</div>
<div class="intro">
<table>
<tr>
<th>Member</th>
<td class="border"><%= link_to community.cached_votes_up.to_s , bookmarker_community_path(community.community_name) %></td>
</tr>
<tr>
<th>Publisher</th>
<td class="border"><%= link_to community.publisher, communities_path(:publisher => community.publisher) if !community.blank? %></td>
</tr>
<tr>
<th class="body">Body</th>
<td class="border"><%= community.body.slice(0,55) if !community.blank? %></td>
</tr>
<tr>
<th class="tag">Tags</th>
<td class="border">
<% community.tags.each do |tag| %>
<span><%= link_to tag.name, {:controller=>'communities', :action=>'index', :tag=>tag.name} %></span>
<% end %>
</td>
</tr>
</table>
</div>
<div class="button">
<%= topic_button(community) %>
<%= uploader_button(community) %>
</div>
<div class="button">
<%= chat_button(community) %>
<%= link_to sanitize('Codes ( ' + community.codes_count.to_s + ' )', community_codes_path(community), :class => 'btn' %>
</div>
<div class="follow">
<span class="bookmark_community" community-id="<%= community.id %>">
<%= render :partial => "communities/bookmark", :locals => {:community => community} %>
</span>
</div>
</div>
</div>
application_helper.rb
def topic_button(community)
last_post = community.community_topics.order('last_active_at DESC').first
if last_post && last_post.last_active_at.today?
link_to sanitize("Forum ("+ community.community_topics.count.to_s+")" , community_community_topics_path(community), :class => 'red_button'
else
link_to sanitize( "Forum ("+ community.community_topics.count.to_s+")" , community_community_topics_path(community), :class => 'button'
end
end
def uploader_button(community)
last_post = community.community_uploaders.order('last_active_at DESC').first
if last_post && last_post.last_active_at.today?
link_to sanitize("Uploader ("+ community.community_uploaders.count.to_s+")" , community_community_uploaders_path(community), :class => 'red_button'
else
link_to sanitize("Uploader ("+ community.community_uploaders.count.to_s+")" , community_community_uploaders_path(community), :class => 'button'
end
end
def chat_button(community)
if !community.comment_threads.last.nil? && community.comment_threads.last.created_at.to_date == Date.current.to_date
link_to sanitize('Chat', chat_community_path(community), :class => 'red_button'
else
link_to sanitize('Chat', chat_community_path(community), :class => 'button'
end
end
/views/communities/_bookmark.html.erb
<% if user_signed_in? %>
<% if current_user.voted_up_on? community %>
<%= link_to(bookmark_community_path(community), :remote => true, :class => 'button') do %>
<i class="icon-remove"></i>
Un-Bookmark
<% end %>
<% else %>
<%= link_to(bookmark_community_path(community) ,:remote => true, :class => 'blue_button') do %>
<i class="icon-bookmark"></i>
Bookmark
<% end %>
<% end %>
<% else %>
<%= link_to(bookmark_community_path(community) , :class => 'blue_button') do %>
<i class="icon-bookmark"></i>
Bookmark
<% end %>
<% end %>