この記事は私の備忘録的なネタです。開発をしていると「has_many」で関連しているレコードの数で並び替えたいケースが発生します。これ毎回どうやってやるんだけっかとググるのですが一発でいい感じの記事にたどり着けなかったりするのでこの記事でまとめておこうと思います。
どういうケースで必要になるか?
例えばこんな場合を想定してみましょう。ライターモデル(Writer)と記事モデル(Article)があり、1つの著者は複数の記事を持ち、1つの記事は1人の著者に所属します。モデルに書くと下のような状態です。
models > writer.rbへの記載内容
1 2 3 4 |
class Writer < ApplicationRecord has_many :article, dependent: :destroy end |
models > articl.rbへの記載内容
1 2 3 4 |
class Articl < ApplicationRecord belongs_to :writer end |
この状態で、持っている記事モデル(Article)が多い順にライターモデル(Writer)を取得していきたいと思います。頑張っているライターランキングを作成したときとかに使うイメージですね。
実装をしてみよう
では実際に書いていきます。今回はデータ取得系のメソッドになるのでライターモデル(Writer)の中に書いていきます。
models > writer.rbへの記載内容
1 2 3 4 5 6 7 8 9 10 11 |
class Writer < ApplicationRecord has_many :article, dependent: :destroy def self.order_by_articles Tag.select('writers.*', 'count(articles.id) AS articles') .left_joins(:articles) .group('writers.id') .order('articles DESC') end end |
こうです。WriterモデルとArticleモデルを結合して、articles数をカウント。writer毎に集計してその数の多い順に並べ替えるということをやっています。
あとはこのメソッドをController側から呼び出してインスタンス変数などに格納して貰えればOKです。呼び出すときは下記のようにします。今回は@writersというインスタンス変数に入れていますが、ここはなんでもいいです。
1 2 3 4 |
def hoge @writers = Writer.order_by_articles end |
以上です。同じことでお困りの方は参考にされてみてください。