🦇
ソート機能(PFいいね多い順/新着順)
コントローラー記述
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