📝

いいね 多い順に並べる

に公開

今回はいいね機能を多い順に表示していきます!

model

has_many :favorited_users, through: :favorites, source: :user

上記のコードを追加します。
このコードに関してはhas_many :favorited_usersは、モデルのインスタンスが複数のfavorited_usersモデルのインスタンスを持つことを意味しています。
through: :favoritesは、中間テーブルであるfavoritesを通じて関連付けを行うことを示しています。
つまり、この関連付けを通じて、モデルのインスタンスは複数のfavoritesモデルのインスタンスを持ち、そしてそれらのfavoritesモデルのインスタンスを
介して複数のfavorited_usersモデルのインスタンスにアクセスすることができます。
source: :userは、favoritesモデルの中でuserという名前のカラムを使ってfavorited_usersモデルのインスタンスを取得することを指定しています。

controller

def index
    to = Time.current.at_end_of_day
        from = (to - 6.day).at_beginning_of_day
        @books = Book.includes(:favorited_users).
          sort_by {|x|
            x.favorited_users.includes(:favorites).where(created_at: from...to).size
          }.reverse
end

解説

to = Time.current.at_end_of_day
現在の日時を表す Time.current を当日の終わりの時間に設定。

from = (to - 6.day).at_beginning_of_day
終了日から6日前の日時を開始日として設定

@books = Book.includes(:favorited_users).

@books = Book.allで投稿されたデータを全て取得し、誰が投稿したかという情報をユーザーテーブルに取得しに行った。
その手間を省くためにmodelに新たに記述したコードによってユーザーの情報がfavorited_usersに格納され、それをincludesの引数に入れてあげることで、事前にユーザーのデータを読み込ませれる。

sort_by {|x| x.favorited_users.includes(:favorites).where(created_at: from...to).size }.reverse

favorited_usersによって関連づけられたユーザーから、from から to の期間に作成された favoritesの数に基づいて、与えられた配列xの要素を並べ替えている。

ブロック変数 |x| を定義しないと、2よりも10,11の方が小さいと判定されてしまう。

最後にreverseをつけることで、昇順ではなく、降順で表示される!

終わりに

今回はsort_byを使用した記述の仕方を紹介したが、
sortでの記述の方法もあるので気になる方はそちらで書いてみるのもいいでしょう。

Discussion