🦇

ソート機能(PFいいね多い順/新着順)

2024/07/19に公開

コントローラー記述

app/posts_controller
def index
    if params[:sort] == 'likes'
      @posts = Post.joins(:likes).group(:id).order('COUNT(likes.id) DESC').page(params[:page]).per(12)
    else
      @posts = Post.order(created_at: :desc).page(params[:page]).per(12)
    end
  end
  • 解説
if params[:sort] == 'likes'
  • ソートの条件分岐。
  • params[:sort]likesに等しいかチェックしている。
  • ユーザーがいいねの多い順にソートを要求している場合に該当する。
@posts = Post.joins(:likes).group(:id).order('COUNT(likes.id) DESC').page(params[:page]).per(10)
  • Post.joins(:likes)投稿と関連するいいねのレコードを結合する。

  • 投稿がいいねを持っていなくても、全ての投稿が取得される。

  • モデル名.joins(:関連モデル)が基本形で、軸となるモデルに対してjoinsメソッドを呼び出し、引数で関連モデルを指定する。

  • group(:id)で各投稿(IDごと)でグループ化する。
    これで投稿ごとにいいねの数を集計できる。

  • order('COUNT(likes.id) DESC')でいいねの数を降順→多い順に並び替える。

@posts = Post.order(created_at: :desc)
  • これは以前、注文一覧を作ったときの並び替え同じ。新着順。

モデル

  • モデルは、いいね機能作成と、投稿機能作成した時に記述しているはず。
app/models/post.rb
class Post < ApplicationRecord
  has_many :likes, dependent: :destroy
end
app/models/like.rb
class Like < ApplicationRecord
  belongs_to :post
end

ルーティング

  • ルーティングも投稿機能実装した時に記述しているはず。
config/routes.rb
scope module: 'public' do
    resources :posts, only: [:index, ・・・

ビュー

app/public/posts/index.html.erb
  <%= link_to '新着順', posts_path(sort: 'new') %>
  <%= link_to 'いいねの多い順', posts_path(sort: 'likes')%>
  • 新着順といいね順をリンクで押せて、選択できるようにする。
    リンク先は一覧で表示させているから、posts_pathで良い。ソート機能のため、(sort: 'new'),(sort: 'likes')で指示する。

終わり。

Discussion