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

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

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

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

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

解決済

RailsでのMySQL8.0を使用した、再帰クエリの書き方

tttkkm
tttkkm

総合スコア10

MySQL

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

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

1回答

0評価

1クリップ

1157閲覧

投稿2020/06/20 02:52

編集2020/06/21 02:43

前提・実現したいこと

お世話になります。
Railsで掲示板を作っています。
スコア順に並び替えたコメントと、それに対するスコア順に並び替えた返信をツリー状に表示したいと考えています。
n-1
n-1-1
n-1-1
n-2
n-2-1
n-3

イメージとしては上記のような、Redditのような形です。
調べてみたところ、ツリー構造の実装には

隣接リストモデル
経路列挙モデル
入れ子集合モデル
閉包テーブルモデル

などがあり、再帰クエリを使えるのなら、ツリー構造には隣接リストが最も適していると
リンク内容
こちらに書いてあり、またSQL文で書いたほうが高速だと
リンク内容
こちらにあったので、MySQLを8.0にアップデートし再帰クエリを用いようと試みました。
しかし初心者のため、SQL文に慣れておらず、またRails内でのSQL文の書き方がわからなかったため、とりあえずRailsの機能で再帰クエリを使おうと、下記のようなコードを書いてみました。

rb

topics_controller.rb @post = @topic.posts.includes(:user).where(parent_post_id: 0).descendents.sort_by{|post| -post.score}

rb

post.rb has_many :children, foreign_key: :parent_post_id, class_name: 'Post' def descendents self.map do |p| p.children.map do |child| [child] + child.descendents end.flatten end end

しかしundefined methodのエラーが出てしまいました。
includesを外してみたり、sort_byを外してみたりしたのですが、問題は解決しませんでした。
初心者のため、何か根本的な勘違いをしているのだと思うのですが、それがどこなのかがわかりません。
できればMySQLを用いた再帰クエリの書き方を、MySQLでは難しいのであれば、Railsでの再帰クエリの書き方をご教授いただければ幸いです。またその他の解決法もお待ちしております。

該当のデータ

sql

+----------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+--------------+------+-----+---------+----------------+ | id | bigint | NO | PRI | NULL | auto_increment | | name | varchar(191) | NO | | | | | content | text | YES | | NULL | | | post_image | varchar(191) | YES | | NULL | | | parent_post_id | int | NO | | 0 | | | upvotes | int | YES | | 0 | | | downvotes | int | YES | | 0 | | | user_id | bigint | NO | MUL | NULL | | | topic_id | bigint | NO | MUL | NULL | | | created_at | datetime | NO | | NULL | | | updated_at | datetime | NO | | NULL | | | score | int | NO | | 0 | | +----------------+--------------+------+-----+---------+----------------+

csv

Post id, name, content, parent_post_id, score 1,"A","隣接リスト最高!",0,2 2,"B","シンプルでいいですよね",1,0 3,"C","アンチパターンですよ、経路列挙モデル使いましょう",1,2 4,"D","入れ子集合モデルの方が良いですよ",3,1 5,"E","こんにちは",0,0

###望む結果
topic
|_ 隣接リスト最高! 2点
| |_ アンチパターンですよ、経路列挙モデル使いましょう 2点
| |_ 入れ子集合モデルの方が良いですよ 1点
| |_ シンプルでいいですよね 0点
|_ こんにちは 0点

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

undefined method `descendents' for #<Post::ActiveRecord_AssociationRelation:0x00...

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

mysql Ver 8.0.20 for Linux on x86_64 (MySQL Community Server - GPL)
Rails 6.0.3.2

試したこと

ここに問題に対して試したことを記載してください。

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

ここにより詳細な情報を記載してください。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

sazi

2020/06/20 03:49

> MySQLを用いた再帰クエリの書き方 テーブルの定義情報と、サンプルデータ、求める結果を追記して下さい。
tttkkm

2020/06/21 02:44

開発環境に問題があり、返信遅れてしまい申し訳ありません。 追記いたしました。このような感じでよろしいでしょうか?不足な点などあればお知らせください。

まだ回答がついていません

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

MySQL

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

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