Edited at

Railsで、中間テーブルのレコード数の多い順にレコードを並び替える方法(orderの中でcountを使用)

More than 1 year has passed since last update.


状況説明

「イベントを参加人数が多い順に表示したい」

言い換えると、中間テーブルにあるイベント毎のユーザーの数(参加人数)を数えて、それが多い順にEventを取得する。

これが以外と調べても出てこなかったので、記事にしておきます。


DB構造


  • eventテーブル

  • userテーブル

  • user_eventsテーブル

user_eventsテーブルでは、それぞれのidを外部キーとして持っています。

その他のカラムはご想像にお任せします。

ユーザーがイベントに参加するとuser_eventsテーブルに、

id
user_id
event_id

1
1
1

2
2
1

3
1
3

4
3
3

といった具合に登録されていきます。


結論

Event.joins(:user_events).group(:event_id).order('count(user_id) desc')

orderの中以外はActiveRecordを使用しています。あまり生のSQLがありすぎるのも嫌なので。

あとはインスタンス変数に入れるなりして、viewでいつも通りeachすればokです!

イベントの順番が参加人数の多い順になっているはず。


ポイント

タイトルにもある通り、orderの中でcountを使用しています。

countと聞くと、Railsの

Event.all.count

=> 12345

の方を想像しがちです。

自分も最初はこれを使おうとしていました。

しかし、これだと ただレコード件数を取得するクエリ になってしまい、肝心のEventのデータなどが持ってこれなくなります。

そこで「orderの中でcountを使えばいいんじゃね?」と思った結果がこのコード。

こっちの書き方の方が良い!などのアドバイスお待ちしています!🙇


参考

こちらの記事などを拝読させていただきました。

ただ、こちらのようなSQLが実行された時の AS hoge を利用する方法は試行錯誤しましたが、うまくいきませんでした。

似たような手法の情報が多いのでもしかしたら、こちらの方向で実装したほうが良いのかもしれません。