ソート機能(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. 投稿一覧ページのビューを編集
サイドバー(検索機能)とメインコンテンツ(投稿一覧)に分けて表示
次回
他人の投稿にコメントできるようにコメント機能を実装