ソート機能(ransack)

内容

投稿の並び順を変えたいので、ransackを用いてソート機能を実装する

ソート機能

1. counter_cultureの導入

投稿をいいねの多い順に並べ替えたいため、postsテーブルにlikes_countというカラムを作りたい
Railsにはcounter_cacheという機能がデフォルトである
→すでにpostsテーブルにデータがある場合、likes_countの値は自動更新されない!
→counter_cultureはcounter_cacheの弱点も補強してくれるような高機能のgem、ということで導入
gemfile

gem 'counter_culture'

ターミナル

% bundle install
% rails s

マイグレーションファイルを生成
ターミナル

% rails generate counter_culture Post likes_count

以下のようなマイグレーションファイルが生成される
db/migrate/2021xxxxxxxx_add_likes_count_to_posts.rb

class AddLikesCountToPosts < ActiveRecord::Migration[6.0]
  def self.up
    add_column :posts, :likes_count, :integer, null: false, default: 0
  end

  def self.down
    remove_column :posts, :likes_count
  end
end

ターミナル

% rails db:migrate

モデルには以下のように記載
model/like.rb

class Like < ApplicationRecord
  belongs_to :post
  counter_culture :post
end

model/post.rb

class Post < ApplicationRecord
  has_many :likes, dependent: :destroy
end

その後、すでにpostsテーブルにたくさんデータがある等の場合、コンソールで以下の様に実行
ターミナル

% rails c
pry(main)> Like.counter_culture_fix_counts

こうすることで、postsテーブルのlikes_countのカラムの中身がアップデートされる
これは便利!

2. ビューの編集(ransack)

1.でいいねの数がpostsテーブルに取得できたので、ビューで人気順に並べ替えれるように編集
その他、投稿の新しい順や距離の長い順等も合わせて並べ替えができるように記述
_search.html.erb

<%= search_form_for @q, url: root_path, class: "search-form" do |f| %>
  <%= f.select(:sorts, {'投稿が新しい順': 'created_at desc', '投稿が古い順': 'created_at asc', '距離が長い順': 'distance desc', '距離が短い順': 'distance asc', '人気順': 'likes_count desc'}, { selected: params[:q][:sorts] }, class: "sort-input") %>
  <%= f.submit "検索", class: "search-btn" %>
<% end %>

※前回の投稿では、検索後にsearch.html.erbに遷移するようにurl等も指定していたが、すべて投稿一覧ページで完結すると思いindex.html.erbに遷移するよう記述を変更した

3. 投稿一覧ページのビューを編集

サイドバー(検索機能)とメインコンテンツ(投稿一覧)に分けて表示

次回

他人の投稿にコメントできるようにコメント機能を実装