各店舗の評価の平均値を一覧表示ページで表示する方法を記述します!
イメージはこんな感じです。
こちらの実装は
Farstep【プログラミング講座】
さんの【Ruby on Rails】星レビュー機能を作ろう(PART1)How To Create a Star Rating with Ruby on Railsを参考にしています。
使用環境
ruby 2.6.5
Ruby on Rails 6.0.3.3
一部、余白の指定でBootstrap4を使用しています。
実装内容
###モデルの実装
class Laundry < ApplicationRecord
def avg_score
unless self.comments.empty?
comments.average(:rate_id).round(1)
else
0.0
end
end
def avg_score_percentage
unless self.comments.empty?
comments.average(:rate_id).round(1).to_f*100/5
else
0.0
end
end
end
はじめにコメントが空かどうかで場合分けをして存在している場合は平均値の計算を行います。
averageメソッドを使用してカラム名の平均値を出します。
round(1)
とすることで小数点第2位に対して四捨五入をします。
avg_score_percentage
メソッドではパーセンテージの計算をしてビューに渡します。
###ビューの実装
コードは以下の通りです。
<div class="average-score mb-3">
<div class="star-rating ml-2">
<div class="star-rating-front" style="width: <%= laundry.avg_score_percentage %>%">★★★★★</div>
<div class="star-rating-back">★★★★★</div>
</div>
<div class="average-score-display">
(<%= laundry.avg_score %>点)
</div>
</div>
.average-score {
display: flex; // ★と点数を横並びにする
justify-content: center;
}
.star-rating {
position: relative;
width: 5em;
height: 1em;
font-size: 17px;
}
.star-rating-front {
position: absolute;
top: 0;
left: 0;
overflow: hidden; // 指定幅からはみ出した部分を隠す。
white-space: nowrap; // widthが足りない時に、折り返さないようにする。
color: #ffcc33;
height: 25px;
}
.star-rating-back {
color: #ccc;
}
2つの5つ星(★★★★★)を用意してその2つを重ね合わせることで実装を行います。
・.star-rating-front
・・・黄色い星の部分、上に重ねて"width: <%= laundry.avg_score_percentage %>%
とすることで幅を指定する。
・.star-rating-back
・・・灰色の星の部分、下におくことで黄色くならなかった部分を埋める。
ポイントとして以下の2点だと思います。
1.overflow: hidden;
を指定。
overflow: hidden;
を指定することで指定幅からはみ出した部分を隠して後ろの灰色の星を表示させます。
ここを指定しないと、せっかく幅を指定しても幅からはみ出した部分が隠れていないため必ず星5つの評価になってしまいます。
overflow: hidden;
なし
2.white-space: nowrap;
とすることでwidthが足りない時に、折り返さないようにしてくれます。
これを指定することで小数点以下の点数も星に反映されます。
white-space: nowrap;
あり
これで評価の平均値を星で表示することができました!