状況説明
「イベントを参加人数が多い順に表示したい」
言い換えると、中間テーブルにあるイベント毎のユーザーの数(参加人数)を数えて、それが多い順に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
を利用する方法は試行錯誤しましたが、うまくいきませんでした。
似たような手法の情報が多いのでもしかしたら、こちらの方向で実装したほうが良いのかもしれません。