目標
- ユーザーの投稿点数ランキング
- 投稿に対して評価点数を合計/平均して、その投稿ユーザーの投稿点数ランキング
- 投稿の点数ランキング(user部分を投稿に変更したら可能です)
- 投稿に対して評価点数を合計/平均して、その投稿の点数ランキング
開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina
前提
※ ▶◯◯ を選択すると、説明等が出てきますので、
よくわからない場合の参考にしていただければと思います。
※数値がまだないユーザーも表示できるよう、
left_joinsとsort_byを使って、ランキング機能を実装します。
※他のランキング方法もあるため、随時投稿していきます。
カラム追加
投稿に対するコメントにて、評価をつけるため追加。
$ rails g migration AddScoreToComments score:integer
class AddScoreToComments < ActiveRecord::Migration[5.2]
def change
add_column :comments, :score, :integer, default: 0
end
end
このままでは点数に差が生まれてきてしまうので、
viewで点数を選択式にできるように記述。
評価:<%= f.number_field :score,min:1,max:5 %>
<% @sum = 0 %>
<% @post.comments.each do |comment| %>
<% @sum += comment.score %>
<% end %>
<%= @sum %>
<% @average = 0 %>
<% @post.comments.each do |comment| %>
<% @average += (comment.score / @user.comments.count) %>
<% end %>
<%= @average %>
準備が出来たので、本題に進みます。
controller
コントローラーが肝になります。
def rank
@users = User.
left_joins(:comments).
distinct.
sort_by do |user|
hoges = user.comments
if hoges.present?
hoges.map(&:score).sum
else
0
end
end.
reverse
end
def rank
@users = User.
left_joins(:comments).
distinct.
sort_by do |user|
hoges = user.comments
if hoges.present?
hoges.map(&:score).sum / hoges.size
else
0
end
end.
reverse
end
補足
・left_joins(:comments):左外部結合と言って、コメントに紐づくuserを全て取得し、 コメントがない場合はnullで取得するメソッドです。こちらの解説がわかりやすいです。 [【Rails】left_joinsメソッドで定義する左外部結合とは?](https://pikawaka.com/rails/left_joins) ・distinct:重複レコードを1つにまとめるためのメソッドであり、 今回の場合はコメントが2つ以上あると、userも2つ以上取得してしまうため、 重複を回避するために使用します。 ・sort_by do |user|:配列を小さい順に並び替えるメソッドです。 値としてはif以降の条件で代入していきます。 ・map(&:score):scoreの値だけ、追加していくメソッドです。 こちらの解説がわかりやすいです。 [Railsでよく見る arr.map(&:id) の意味](https://qiita.com/s_tatsuki/items/869af9c0c33d9d650f3f) ・reverse:sort_byで小さい順に並び替えたため、逆にしています。 ただし、同数値の場合、新しい順になるため、注意が必要です。 ここは解決出来ましたら再度更新します。 ・hoges.size:hogesの数を取得しています。その数値を元に平均を出しています。view
下記のようにeach降順順で表示可能
app/views/users/rank.html.erbを作成後、
<% @users.each do |user| %>
<%= link_to user_path(user) do %>
<%= user.name %><br>
<% end %>
<% end %>
routing
get '/rank', to: 'users#rank'
参考サイト
[Railsでお手軽ランキング機能]
(https://qiita.com/mitsumitsu1128/items/18fa5e49a27e727f00b4)
【Rails】ランキング機能の実装
まとめ
今回は高いスコアを投稿しているユーザーを表示したかったため、
このような記述となりましたが、
あまり実用的ではないかもしれません。
ただ、これらのランキングを使えば、
点数を高く評価している人だけ、または低い人だけに
アプローチを取ることができるため、営業向きのランキングかと思います。
また投稿の点数ランキングは口コミランキングなどを実装したい場合は、
実用的な記述になるかと思います。