🌊

Rails|過去一週間でいいねの合計カウントが多い順に投稿を表示(sortを用いた方法)

2023/08/02に公開

表示結果は前回の記事と同じ内容になります。
今回は、sortメソッドを用いた方法で記述します。
https://zenn.dev/airiin/articles/5490476fb2ca6f

開発環境

ruby 3.1.2p20
Rails 6.1.7.4
Cloud9

前提

Userモデル、Bookモデル、Favoriteモデルは作成済み。

step1 モデル間のアソシエーション

Userモデル

user.rb
  has_many :books, dependent: :destroy
  has_many :favorites, dependent: :destroy

Favoriteモデル

favorite.rb
  belongs_to :user
  belongs_to :book

Bookモデル

book.rb
  belongs_to :user
  has_many :favorites, dependent: :destroy

step2 コントローラの編集

次に、booksコントローラを編集します。

books_controller.rb
  def index
    to  = Time.current.at_end_of_day
    from  = (to - 6.day).at_beginning_of_day
    @books = Book.all.sort {|a,b| 
      b.favorites.where(created_at: from...to).size <=> 
      a.favorites.where(created_at: from...to).size
    }
    @book = Book.new
  end

まず、

    to = Time.current.at_end_of_day
    from = (to - 6.day).at_beginning_of_day

この部分を解説します。

Time.current
config/application.rbに設定してあるタイムゾーンを元に現在日時を取得します。

.at_end_of_day
時刻を23:59:59に設定します。

.at_begginning_of_day
時刻を0:00:00に設定します。

つまり、

to = Time.current.at_end_of_day は、
本日の23:59:59を toという変数に入れる、という意味です。

from = (to - 6.day).at_beginning_of_day は、
to の 6日前の 0:00を fromという変数に入れる、という意味です。

最後に、

    @books = Book.all.sort {|a,b| 
      b.favorites.where(created_at: from...to).size <=> 
      a.favorites.where(created_at: from...to).size
    }

この部分を解説します。

Book.all
ここで Bookモデルのデータを全て取得します。

sort {|a,b| ... <=> ...}
これは sortメソッドです。配列の要素を並び替えるために使用します。
配列の要素が {}内で a, bに代入され、値が比較され、並べ替えられます。

https://www.sejuku.net/blog/15267

b.favorites.where(created_at: from...to).size
a.favorites.where(created_at: from...to).size
この部分は from から toの期間内に createされた 全てのfavoritesのデータの数を表しています。

つまり、

Book.all.sort {|a,b| 
      b.favorites.where(created_at: from...to).size <=> 
      a.favorites.where(created_at: from...to).size
    }

この部分では、

  1. Bookモデルの全データを取得
  2. Bookモデルのうち、 from から to の期間内にcreateされた favoritesデータ数を取得
  3. 各Bookモデルの 期間内の favoritesのデータ数を1つずつa, bに代入して、大きさを比較して、大きい順に並び替え

をしているということです。

*sortブロック内で、

  b.favorites.where(created_at: from...to).size
  a.favorites.where(created_at: from...to).size

この部分の a と bを逆にすると、結果が昇順で表示されます。

Discussion