質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

1回答

1260閲覧

Rails 非同期処理導入で発生するrenderの嵐

NaoyaAbe

総合スコア3

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

1クリップ

投稿2021/06/16 03:21

編集2021/06/29 10:12

前提

ここに質問の内容を詳しく書いてください。
(例)現在,Railsで転職用ポートフォリを作成中です。
現在、投稿機能、投稿に対するコメント機能、投稿に対するいいね機能などを実装しました。

投稿に対するいいね機能を非同期(Ajax)で実装しています。

いいねボタンを押した時にいいね解除ボタンを表示させるため、パーシャル(_like.html.haml)を作成しています。

いいねボタンを押したときにcreate.js.hamlにて、id: "post-#{post.id}-likes"のhtmlに_like.html.hamlをレンダリングする仕様です。

問題点

実際のいいね、いいね解除は問題なく動作するのですが、投稿一覧ページ(いいねボタンが大量に存在する) にて、
_like.html.haml が繰り返しによって各投稿ごとにrenderされてしまうため、ページ読み込みに時間がかかってしまいます。

イメージ説明

※大まかな構造を説明するため、不要な部分を除いています。 **投稿一覧ページ** - @post.each do |post| = post.content %div{ id: "post-#{post.id}-likes" } = render 'like', post: post
**_like.html.haml** - if user_signed_in? - if post.already_liked?(current_user) = link_to post_like_path(post, post.likes), method: :delete, remote: true do %font .fas.fa-heart.likes-heart-already{ id: 'delete-like-link' } - else = link_to post_likes_path(post), method: :post, remote: true do %font .far.fa-heart.likes-heart-yet{ id: 'create-like-link' }
**create.js.haml** $("#post-#{@post.id}-likes").html("#{j(render('likes/like', post: @post))}");
**likes_controller.rb** class LikesController < ApplicationController before_action :authenticate_user! def create @post = Post.find(params[:post_id]) @like = current_user.likes.build(post_id: @post.id) @like.save respond_to do |format| format.js end end def destroy @post = Post.find(params[:post_id]) Like.find_by(post_id: @post.id, user_id: current_user.id).destroy respond_to do |format| format.js end end end
** posts_controller.rb ** #追加しました‼︎ 6/29 class PostsController < ApplicationController def index @posts = current_user.feed.eager_load(:user, :likes).page(params[:page]) #feedメソッドはUserモデルに定義 @post = Post.new @like = Like.new end end ** user.rb ** #追加しました‼︎ 6/29 class User < ApplicationRecord def feed following_ids = "SELECT following_id FROM relationships WHERE follower_id = :user_id" Post.where("posts.user_id IN (#{following_ids}) OR posts.user_id = :user_id", user_id: id) end end

考えている解決策

通常の投稿一覧ページへのアクセスではrenderを使用しない方法を考えているのですが、いいね機能の非同期処理を実装するにあたって_likeパーシャル作成は避けられないため、コードが重複してしまうので、悩んでいます。

初めての質問のため、説明不足、失礼な部分があるかもしれません。
何か良い方法がありましたらご教授お願いいたします。

補足情報(バージョンなど)

rails', '~> 5.2.1'
ruby '2.6.6'
docker環境

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NaoyaAbe

2021/06/16 13:28

見ていただきありがとうございます! 今likesコントローラを載せさせていただきました!
winterboum

2021/06/16 22:56

繰り返し要素が見当たりませんね、、、 すみません力不足です
NaoyaAbe

2021/06/18 10:08

コードを見ていただき、ありがとうございました!
asm

2021/06/27 00:07

投稿一覧側のコントローラはどうなっていますか?
NaoyaAbe

2021/06/29 10:21

お返事が遅くなり申し訳ありません! コードを見ていただき、ありがとうございます! ただいま、投稿一覧のコントローラと、そのコントローラで使用しているfeedメソッドの定義部分を載せました。 私自身の考えでは、コントローラでのデータ取得方法などが原因ではないと考えています。 「ajaxで非同期処理を行うためにパーシャル化したはいいが、ページへの同期アクセスにてパーシャルのrenderが大量発生してしまう。」 ということの解決策でなにか思い当たることはありますでしょうか。 よろしく願いいたします。 イメージ的には、eachメソッドでrenderが大量に発生することを防止するcollectionのオプションみたいな方法(大量の繰り返しでもパーシャルを一度しかrenderしない)がありそうで、見つからず、苦戦しています。
guest

回答1

0

ベストアンサー

_like.html.hamlと同フォルダに

haml

1 = post.content 2 %div{ id: "post-#{post.id}-likes" } 3 = yield

_post_layout.html.hamlとして保存し

haml

1= render partial: 'like', layout: 'post_layout', collection: @posts, as: :post

とすることは可能かと思いますが奇妙な構成になるのが気掛かりです。


config.action_view.logger = nilにてログを抑制すると改善しそうな気もします

投稿2021/06/30 01:07

asm

総合スコア15149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NaoyaAbe

2021/07/18 07:17

回答していただき、ありがとうございます! 実装までに時間がかかってしまい、お返事が遅くなりました! 回答で記入していただいた方法の、'_post_layout.html.haml'を作り、 = render partial: 'like', layout: 'post_layout', collection: @posts, as: :post とすることで、renderの嵐を抑制することができました! yieldの使い方の勉強になりました! ありがとうござました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問