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

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

新規登録して質問してみよう
ただいま回答率
85.35%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

1回答

1012閲覧

Railsでの、点数順でのコメントの並び替えと、その下にツリー状で返信を表示させる方法

tttkkm

総合スコア10

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

1クリップ

投稿2020/05/28 14:08

編集2020/05/29 18:24

前提・実現したいこと

お世話になります。
現在railsで掲示板サイトを作っています。
コメントにユーザーからの投票による点数を設定し、点数順で並び替え、その下にそのコメントへの返信を表示させたいと考えております。
イメージとしてはRedditのように

コメント
返信
返信の返信


といった形でツリー状に続いていくようにしたいです。

コメントに、parent_post_idというカラムを設け、そこに親コメントのidを挿入しています。親コメントの場合はdefaultで0です。

発生している問題・エラーメッセージ

どうすれば思い通りの並び方を実現できるのかがわかりません。sort_byを用いてscoreとparent_post_idで並び替えればどうなるかと試してましたが、できませんでした。
parent_post_idが0の場合はpost.idを取得し、parent_post_idが設定されている場合はparent_post_idを取得し、それで並び替える、というふうにすればできるのではないかと思いましたが、どうすればそれを実現できるのかがわかりません。

該当のソースコード

rb

1controller 2 def index 3 @posts= @topic.posts.sort_by{ |p| [p.score, p.parent_post_id] }.reverse 4 end

erb

1<% posts.each do |post| %> 2 <% if post.parent_post_id == 0 %> 3 <div class="card"> 4 <% else %> 5 <div class="card reply"> 6 <% end %> 7 <div class="card-body post-card"> 8 <div class="row align-items-center"> 9 <div class="col-1 text-center"> 10 <div id="vote-actions-<%= post.id %>" class="vote" data-id="<%=post.id%>"> 11 <div class="fa fa-arrow-up upvote <%= is_upvoted post %> "></div> 12 <span class="font-weight-bold score"><%= post.score%></span> 13 <div class="fa fa-arrow-down downvote <%= is_downvoted post %>"></div> 14 </div> 15 </div> 16 <div class="col-11"> 17 <small class="card-title"> 18 <%= link_to post.user.name , profile_path(post.user.userid) %> 19 <%= post.user.karma %> 20 <span class ="float-right"><%= post.created_at.strftime("%Y-%m-%d %H:%M:%S")%></span> 21 </small> 22 <div class="card-text"> 23 <% if post.post_image.present? %> 24 <%= image_tag post.post_image.thumb50.url, class: "post-image"%> 25 <% end %> 26 <br> 27 <p><%= safe_join(post.content.split("\n"),tag(:br)) %></p> 28 </div> 29 30 <% unless current_user.id == post.user_id || post.parent_id == 0%> 31 <button type="button" class="btn reply-btn" data-toggle="modal" data-target="#replyModal" data-parent= <%= post.id %>> 32 <i class="fas fa-plus"></i>返信する 33 </button> 34 <% end %> 35 36 <div class="card-info float-right"> 37 38 <% if current_user.id == post.user_id %> 39 <%= link_to(edit_post_path(post)) do %> 40 <i class="fas fa-pen ml-3"></i> 41 <% end %> 42 <%= link_to(post, method: :delete, data: { confirm: 'Are you sure?' }) do %> 43 <i class="far fa-trash-alt ml-3"></i> 44 <% end %> 45 <% end %> 46 </div> 47 </div> 48 </div> 49 </div> 50 </div> 51 52 <% end %> 53 54 55 56

試したこと

sort_byでscoreとparent_post_idで並び替えてみた。

補足情報(FW/ツールのバージョンなど)

Rails 6.0.3.1
mysql Ver 14.14 Distrib 5.5.62, for Linux (x86_64) using readline 5.1

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

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

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

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

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

guest

回答1

0

Rails以前に生SQLで似たようなことをやった覚えがありますが、もうすっかり忘れています。。。
「検索の結果がそうなっている」のではなく、「検索した結果をそう並べる」のでよければ。
この場合厄介なのは親のparent_post_idが0なこと。もし自身のidと等しくする変更が可能ならば

@topic.posts.group_by{|post| post.parent_post_id}. sort_by{|id,posts| -(posts.find{|post| post.id == id}.score)}. values.flatten

でしょうか。
だめだと一回では無理かと。同じ親の子を集めるのは簡単なのですが、親も一緒に集めるのが難しい。

parents = @topic.posts.select{|post| post.parent_post_id == 0}.sort_by{|post| -post.score} @posts = parents.map{|parent| [ parent ,@topic.posts.select{|post| post.parent_post_id == parent.id}] }.flatten

かな
試していないです。

投稿2020/05/28 23:09

winterboum

総合スコア23567

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

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

tttkkm

2020/05/29 04:24

回答ありがとうございます。 下のコードで一階層分は並べることができました! けれども返信に対する返信は表示されなくなってしまいました。 Redditのように コメント   返信     返信の返信・・・ というふうにツリー状につなげていくにはどうすればいいのでしょうか? viewでの操作の問題なのでしょうか? 質問が言葉足らずだったので修正させていただきました。
winterboum

2020/05/29 08:22

ああ、そうなってるのか。 返信に二つ返信がつくとか、コメントに二つ返信がつくとか枝分かれはありますか? 階層を下るに連れて IDは必ず大きくなる と考えてよいですか?
tttkkm

2020/05/29 09:32

回答ありがとうございます。 はい、2つ付く場合も、枝分かれもあります。 下るに連れてIDは必ず大きくなります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問