初めに
ポートフォリオテーマとして業者のレビューサイトを作成しています。
以下の画像のようなレビューサイトを作っていこうと思います。
※自分用でまとめてますので、分かり辛かったらすいません。
また理解不足・誤りがあったらコメント頂けますと幸いです。m(__)m<ヨロシクオネガイシマス
前提条件
①今回の記事では応用機能のみ※平均値算出や平均点が大きい順に並び替えについて紹介いたします
②今回の記事では基本機能は実装済みとして進めます。詳しくは下記URLより参考にしてください
[rails初心者]複数権限でのログインを使ったレビューサイトの作成(基本)
今回作成するレビュー機能について
・評価データの平均値算出
・平均値の大きい順に並べ替え
主なやること
・モデルの編集(平均値算出処理実装)
・コントローラの編集(並べ替え機能実装)
・ビューページの編集
開発環境
・rails 6.1.7・ruby 3.1.2
・raty 3.1.1
・jquery 3.6.1
・bootstrap 4.5
評価点の平均値算出について
モデルの編集
今回は業者(trader)の一覧表示をするときに平均値を使いたいので、traderモデルにメソッドを作成します
##評価点の平均値
def review_average(trader)
if trader.reviews.count >= 1 #顧客(client)に評価されたことがあるか否かを確認
reviews=Review.where(trader_id: trader.id).pluck(:star)#starカラムに保存されている評価点数を取得
#reviews.map!(&:to_i)#取得した変数(reviews)が文字列の場合、数列型へ変更しましょう
reviews.sum.fdiv(reviews.length).round(1)#取得した変数をもとに平均値を算出
#round(1)とすることで小数点第2位に対して四捨五入をします。
else
0.0 #顧客(client)に評価されたことが無い場合、平均値を0.0に設定
end
end
コントローラの記述
##詳細ページ系に使う場合
@trader = Trader.find(params[:id])
##一覧ページに使う場合
@traders = Trader.all
ビューファイルの記述
##詳細ページに使う場合
<%= @trader.review_average(@trader) %>
##一覧ページに使う場合
<% @traders.each do |trader| %>
<%= trader.review_average(trader) %>
<% end %>
ポイント:表示の仕方によって使い分ける(一覧か詳細か)
完成イメージ
では完成形を見てみましょう!※先程のviewファイルの記述とは一部一致しない箇所があります。
①一覧ページの場合(赤枠の箇所)
②詳細ページの場合(赤枠の箇所)
平均値の大きい順に並び替え
今回はorder
メソッドを使って並べ替えを行います。
ただ単純にorder
メソッドだけでは並べ替えはできなかったので、その経緯と解説をまとめました。
1-0平均値算出に必要なことについて
まず平均値の計算式は、画像の通りです。
基本的には(avg(カラム名))
を使って計算を行いますが、いくつか情報が足りない。。。
だからproup
やpluck
メソッドを使おうと思います。
1-1足りない情報とは
次の2点です。
・(分母の)個数は何をもとに決めればいいのか
・何個分の平均値を算出すればいいのか
まず分母の個数について・・・
今回は特定の業者(trader)に向けて評価された点数の平均値を算出します。
つまり①評価点の個数
を代入する + ②特定の業者
である・・・これらの条件を満たせればいいと考えられます。
したがって、次の画像の水色枠内の個数分が入ればいいことになります。
次に算出結果の個数について・・・
今回は各業者(trader)の評価平均値を算出します。
つまり業者
の数分だけ算出すればいいと考えられます。
したがって、次の画像の赤枠内の個数分が入ればいいことになります。
1-2解決策
端的に申し上げると次の通りです。
・(分母の)個数は何をもとに決めればいいのか → groupメソッドを使用
・何個分の平均値を算出すればいいのか → pluckメソッドを使用
詳しい内容については、分かりやすいサイトがあるのでよかったら「参考資料について」をご覧ください
ポイント① group → 水色枠をまとめるメソッド(業者IDごとにデータをまとめられる)
ポイント② pluck → 赤枠を返り値として扱うメソッド(業者IDの数分だけ返り値が存在する)
ポイント③ (avg(star)) → 黄緑枠は算出した平均値の結果
返り値について
個人的に分かりやすい記事のリンクを貼っときます
引数・戻り値はこうやって理解する
2-1コントローラの記述
def ○○○○
@traders = Kaminari.paginate_array(Trader.find(Review.group(:trader_id).order('avg(star) desc').pluck(:trader_id))).page(params[:page])
end
ポイント①ページネーションは「Kaminari.paginate_array
」の書き方を採用 → 配列(Traderモデル)があるため
ポイント②並び替えは order メソッドを使用
ポイント③ group は「trader_id」を指定 → 指定したカラム(trader_id)のレコード(業者)ごとにデータ(評価点)をまとめるため
ポイント④ pluck も「trader_id」を指定 → reviewテーブルの特定のカラム(trader_id)の値(数分)だけ取得したい → 業者毎に表示可能
ポイント⑤ (avg(star)) → 評価点の平均値算出
こちらも詳しくは参考資料をご覧ください
2-2ビューファイルの記述
※「評価点の平均値算出について」で作成したビューファイルの記述でもOK<% @traders.each do |trader| %>
<%= trader.name %>
<%= trader.○○○○ %>
<%= trader.review_average(trader) %>
<% end %>
完成イメージ
ポイント:評価する毎に一覧の表記順が変わればOK
さいごに
今回PF作成のテーマとしてレビューサイトを作ってみました。
まだ学習中の身なので理解不足・誤りがあったらコメント頂けますと幸いです。m(__)m<ヨロシクオネガイシマス
感想
今回はレビュー機能の応用ということで、平均値の算出
,並べ替え
を実装しました。
基礎学習時(Bookers)とはまた違った手法や記述式が必要であり、更に過去に全く同じことをした人がいないため
試行錯誤しながらの実装になりました。
また今回の記事には書いていませんが複数権限でのログインも扱っているため、
コントローラやビューファイルの使い分・ルーティングの複雑化など
設計書を作っていないおかげで大変でした。
参考資料
[Ruby on Rails]ランキング表示(合計、平均値)
order | Railsドキュメント
[Rails order]メソッドを使って取得したデータを並び替えよう!
[Rails group]メソッドの使い方とは?仕組みを図解で丁寧に解説!
[Rails]便利なpluckメソッドの使い方をマスターしよう!