🐣
過去1週間のいいねの数が多い順に投稿を表示する
[Ruby on Rails] で過去1週間のいいねの数が多い順に投稿を表示する
アソシエーション
user.rb
has_many :books, dependent: :destroy
has_many :favorites, dependent: :destroy!
book.rb
belongs_to :user
has_many :favorites, dependent: :destroy
has_many :favorited_users, through: :favorites, source: :user
解説
多対多のアソシエーションの場合
has_many:
has_many:
を指定します。
-
through
「経由する」という意味で、中間テーブルを経由して、関連先のオブジェクトを取得することができます。 -
source
多対多の関連先のモデル名を指定するオプション
なので今回は favoritesテーブルを経由して Userモデルのオブジェクトを取得するという意味になります。
favorite.rb
belongs_to :user
belongs_to :book
コントローラー
books_controller.rb
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
@book = Book.new
end
解説
to = Time.current.at_end_of_day
- Time.current は TimeWithZone クラスを使用している
- Time.current で config/application に指定してある日時を取得している
- at_end_of_day でその日の終わりを指定している
from = (to - 6.day).at_beginning_of_day
- 一週間という意味
@books = Book.includes(:favorites)
- 前まではBook.all を使用していた
- includes とは関連付けられているモデルを取得するメソッドで、無駄なSQL文を出したくない時に使用する
- includes の後ろの ()でモデルを指定する
sort_by {|x| x.favorited_users.includes(:favorites).where(created_at: from...to).size}.reverse
- sort_by で配列の中から昇順に取り出し、reverseで降順で表示させる
- where メソッドは()の中の条件に合うレコードを取得したりするメソッド
こちらの記事を参考にさせていただきました。
Discussion