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

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

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

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

Ruby on Rails

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

Q&A

解決済

1回答

1685閲覧

ActiveRecoedで2つのカラムの組み合わせが一意になるようにレコードを取得したいです。

ryohei-buruki

総合スコア7

Ruby on Rails 5

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

Ruby on Rails

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

0グッド

0クリップ

投稿2019/07/27 13:46

前提・実現したいこと

アプリの中で記事(article)にコメントをできるようにしています。
コメントの表示のために、ActiveRecoedで2つのカラムの組み合わせが一意になるようにレコードを取得したいです。
また、新しい順(comments.idが大きい順)に取得したいと思っています。

現状

|id|comment|user_id|article_id|
|:--|:--:|--:|
|1|コメント1|1|1|
|2|コメント2|1|2|
|3|コメント3|2|2|
|4|コメント4|2|3|
|5|コメント5|1|2|

commentsテーブルがuserとarticleのidを持っています。
(user_id, article_id)の組み合わせが一意になるように、新しい順でカラムを取得したいです。

試したこと

Comment.select("DISTINCT ON (article_id, user_id) *") Comment Load (0.6ms) SELECT DISTINCT ON (article_id, user_id) * FROM "comments"

これで(user_id, article_id)の組み合わせは一意に取り出せています。
ですが、取得できるレコードが[コメント1,コメント2,コメント3,コメント4]になってしまいます。

試しに降順にしてみました

Comment.order(id: "DESC").select("DISTINCT ON (article_id, user_id) *") Comment Load (2.3ms) SELECT DISTINCT ON (article_id, user_id) * FROM "comments" ORDER BY "comments"."id" DESC Comment Load (1.0ms) SELECT DISTINCT ON (article_id, user_id) * FROM "comments" ORDER BY "comments"."id" DESC LIMIT $1 [["LIMIT", 4]] => #<Comment::ActiveRecord_Relation:0x3fec3bd53fb0>

するとActiveRecordが1つしか返ってこず、また、SQLが2回走ってしまいます。
[コメント5,コメント4,コメント3,コメント1]というように、「コメント2」ではなく「コメント5」を取得できるようにしたいです。よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

動作未検証なので調整しないとダメだと思いますが。どうでしょう。

ポイントは user_id と article_id で グループ化して MAX(id)で最新のもののみ取得しているところ

rb

1Commant.joins(<<~SQL) 2 INNER JOIN 3 (SELECT MAX(id) AS id, user_id, article_id FROM comments GROUP BY user_id, article_id) A ON 4 comments.id = A.id 5SQL

投稿2019/07/29 10:02

SaitoJP

総合スコア22

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

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

ryohei-buruki

2019/08/08 12:27

回答ありがとうございます!返信遅れてすみません。 動作確認をしたところ、期待していた結果にかなり近いものが得られました。 ただ一点、limitで取得する件数を制限した際に、最新のコメントを取得できていない状況です。 (user_id, article_id)のグループの中での最新は取れていますが、そもそも最新のコメントの(user_id, article_id)のグループが制限された状態で作られるグループに含まれていないのが原因だと思います。 created_atやidの大きい順に(user_id, article_id)のグループを作る方法があれば教えていただきたいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問