ブログアプリを製作中です。
機能の一部としてユーザーが記事をストックしたり、ライクしたりができます。
表示速度を改善するためにN+1問題を解決しようとしています。
いくつかのN+1問題は解決できたのですが、検索、検討しても解決できない問題が出てきました。
現在、ユーザーのステータスに応じて、ストック機能、ライク機能のアイコン表示を変えています。
その際、ストックされているか(liked?)、ライクされているか(stocked?)を検証する過程でN+1問題が発生しているようです。
Userモデル has_many :articles, dependent: :destroy has_many :likes, dependent: :destroy has_many :article_stocks, dependent: :destroy
Articleモデル belongs_to :user has_many :likes, dependent: :destroy has_many :liked_users, through: :likes, source: :user has_many :article_stocks, dependent: :destroy has_many :stocked_user, through: :article_stocks, source: :user def liked?(user) liked_users.include?(user) end def stocked?(user) stocked_user.include?(user) end
Likeモデル belongs_to :user belongs_to :article counter_culture :article
Article_stockモデル belongs_to :user belongs_to :article counter_culture :article
aritcles_controller @q = Article.with_attached_image.includes(:tags, user: { image_attachment: :blob }).includes(:liked_users, :stocked_user).ransack(params[:q]) @articles = @q.result(distinct: true).page(params[:page] **.includes(:liked_users, :stocked_user)←この部分を正したいです。**
article/index.html.erb <% @articles.each do |article| %> <span id="like-of-<%= article.id %>"> <%= render "likes/like", article: article %> </span> <span id="stock-of-<%= article.id %> "> <%= render "article_stocks/stock", article: article %> </span <% end %>
likes/like <% if current_user != article.user && user_signed_in? %> <span class="like"> **<% if article.liked?(current_user) %> ←この部分でN+1が発生しています。** <%= link_to "", like_path(article.likes.find_by(user_id: current_user.id)), method: :delete, class:"fas fa-heart", remote: true %> <%= link_to "#{article.likes_count}", likes_path(article_id: article.id)%> <% else %> <%= link_to "", likes_path(article_id: article.id), method: :post, class:"far fa-heart", remote: true %> <%= link_to "#{article.likes_count}", likes_path(article_id: article.id)%> <% end %> </span> <% else %> <span class="far fa-heart" style="color:gray;"></span> <%= link_to "#{article.likes_count}", likes_path(article_id: article.id), :style=> "color: gray;" %> <% end %>
article_stocks/stock <% if user_signed_in? %> <span class="stock"> **<% if article.stocked?(current_user) %> ←この部分でN+1がおきています。** <%= link_to article_stock_path(article.article_stocks.find_by(user_id: current_user.id)), method: :delete , remote: true, data: { confirm: 'ストックをはずしますか?' } do %> <%= content_tag :i, "", class:"fas fa-folder", :style=>"color: brown;" %> <%= article.article_stocks_count %> <% end %> <% else %> <%= link_to article_stocks_path(article_id: article.id), method: :post , remote: true , data: { confirm: 'ストックしますか?' }, :style=>"color: gray;" do %> <%= content_tag :i, "", class:"far fa-folder-open" %> <%= article.article_stocks_count %> <% end %> </span> <% end %> <% else %> <span style="color:gray;"> <%= content_tag :span, nil, class:"far fa-folder-open" %> <%= article.article_stocks_count %> </span> <% end %>
他に必要な情報がありましたら、ご指摘お願いします。
解決策わかる方ご教授よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/16 00:28
2019/09/16 00:36 編集
2019/09/16 00:44
2019/09/16 00:52
2019/09/16 08:16
2019/09/17 09:12