[rails初心者]複数権限でのログインを使ったレビューサイトの作成（応用）

<h2>初めに

ポートフォリオテーマとして業者のレビューサイトを作成しています。<br>以下の画像のようなレビューサイトを作っていこうと思います。

![top画面１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822721/75cffe6d-1714-fc3c-9ad8-068addf06205.png)

※自分用でまとめてますので、分かり辛かったらすいません。<br>また理解不足・誤りがあったらコメント頂けますと幸いです。m(__)m<ﾖﾛｼｸｵﾈｶﾞｲｼﾏｽ

<h2>前提条件</h2>

<p>
①今回の記事では応用機能のみ※平均値算出や平均点が大きい順に並び替えについて紹介いたします<br>
②今回の記事では基本機能は実装済みとして進めます。詳しくは下記URLより参考にしてください<br>

[[rails初心者]複数権限でのログインを使ったレビューサイトの作成（基本）](https://qiita.com/about10/items/0e376c84022f2ac238d0)
</p>
<h2>今回作成するレビュー機能について</h2>

・評価データの平均値算出
・平均値の大きい順に並べ替え
<h2>主なやること</h2>

・モデルの編集（平均値算出処理実装）
・コントローラの編集（並べ替え機能実装）
・ビューページの編集

<h2>開発環境</h2>
・rails 6.1.7<br>
・ruby 3.1.2 <br>
・raty 3.1.1<br>
・jquery 3.6.1<br>
・bootstrap 4.5

<h2>評価点の平均値算出について</h2>
<h5>モデルの編集</h5>
今回は業者（trader）の一覧表示をするときに平均値を使いたいので、<br>
traderモデルにメソッドを作成します

```:app/models/trader.rb
  ##評価点の平均値
  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
```
<h5>コントローラの記述</h5>

```:app/controllers/平均値を表示したいファイルに関係するコントローラ
##詳細ページ系に使う場合
 @trader = Trader.find(params[:id])

##一覧ページに使う場合
 @traders = Trader.all
```

<h5>ビューファイルの記述</h5>

```:app/views/平均値を表示したいファイル
##詳細ページに使う場合
<%= @trader.review_average(@trader) %>

##一覧ページに使う場合
<% @traders.each do |trader| %>
  <%= trader.review_average(trader) %>
<% end %>
```
:::note info
ポイント：表示の仕方によって使い分ける（一覧か詳細か）
:::

<h3>完成イメージ</h3>

では完成形を見てみましょう！※先程のviewファイルの記述とは一部一致しない箇所があります。<br>
①一覧ページの場合(赤枠の箇所)
![top画面１ー１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822721/96f15df8-66a7-6b92-f472-3cc148924b03.png)
②詳細ページの場合(赤枠の箇所)
![評価一覧client側１ー１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822721/4ca61b71-2934-47f4-6b64-ed1ca278b964.png)

<h2>平均値の大きい順に並び替え</h2>

今回は`order`メソッドを使って並べ替えを行います。
ただ単純に`order`メソッドだけでは並べ替えはできなかったので、その経緯と解説をまとめました。

<h5>1-0平均値算出に必要なことについて</h5>
まず平均値の計算式は、画像の通りです。

![2e02c5b8272ecf9713feaa492178289f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822721/6e66de6d-72dd-6921-1c02-c521b5912a38.png)
基本的には`(avg(カラム名))`を使って計算を行いますが、いくつか情報が足りない。。。
だから`proup`や`pluck`メソッドを使おうと思います。

<h5>1-1足りない情報とは</h5>

次の２点です。
・(分母の)個数は何をもとに決めればいいのか
・何個分の平均値を算出すればいいのか

まず分母の個数について・・・
今回は特定の業者(trader)に向けて評価された点数の平均値を算出します。
つまり①`評価点の個数`を代入する + ②`特定の業者`である・・・これらの条件を満たせればいいと考えられます。
したがって、次の画像の**水色枠内の個数分**が入ればいいことになります。
![並び替えイメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822721/a5ce85fa-3658-f8c5-5ea2-758d70fa0b40.png)

次に算出結果の個数について・・・
今回は各業者(trader)の評価平均値を算出します。
つまり`業者`の数分だけ算出すればいいと考えられます。
したがって、次の画像の**赤枠内の個数分**が入ればいいことになります。
![並び替えイメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822721/a5ce85fa-3658-f8c5-5ea2-758d70fa0b40.png)

<h5>1-2解決策</h5>

端的に申し上げると次の通りです。
・(分母の)個数は何をもとに決めればいいのか　→　**group**メソッドを使用
・何個分の平均値を算出すればいいのか　　　 →　**pluck**メソッドを使用

詳しい内容については、分かりやすいサイトがあるのでよかったら「参考資料について」をご覧ください
<details>
<summary>参考資料について</summary>

[[Rails group]メソッドの使い方とは？仕組みを図解で丁寧に解説！](https://pikawaka.com/rails/group#%E9%96%A2%E9%80%A3%E5%85%88%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92group%E3%81%A7%E3%81%BE%E3%81%A8%E3%82%81%E3%81%A6%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)
[[Rails]便利なpluckメソッドの使い方をマスターしよう！](https://pikawaka.com/rails/pluck)</details>

![並び替えイメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822721/a5ce85fa-3658-f8c5-5ea2-758d70fa0b40.png)

:::note info
ポイント① **group**  → 水色枠をまとめるメソッド(業者IDごとにデータをまとめられる)
ポイント② **pluck**  → 赤枠を返り値として扱うメソッド(業者IDの数分だけ返り値が存在する)
ポイント③ **(avg(star))** → 黄緑枠は算出した平均値の結果
:::

<details>
<summary>返り値について</summary>

個人的に分かりやすい記事のリンクを貼っときます
[引数・戻り値はこうやって理解する](https://blog.senseshare.jp/argument.html)</details>

<h5>2-1コントローラの記述</h5>

```:app/controllers/平均値を表示したいファイルに関係するコントローラ
def ○○○○
  @traders = Kaminari.paginate_array(Trader.find(Review.group(:trader_id).order('avg(star) desc').pluck(:trader_id))).page(params[:page])
end
```

:::note info
ポイント①ページネーションは「`Kaminari.paginate_array`」の書き方を採用 → 配列(Traderモデル)があるため
:::
:::note info
ポイント②並び替えは **order** メソッドを使用
:::
:::note info
ポイント③ **group** は「trader_id」を指定 → 指定したカラム(trader_id)のレコード(業者)ごとにデータ(評価点)をまとめるため
:::
:::note info
ポイント④ **pluck** も「trader_id」を指定 → reviewテーブルの特定のカラム(trader_id)の値(数分)だけ取得したい → 業者毎に表示可能
:::
:::note info
ポイント⑤ **(avg(star))** → 評価点の平均値算出
:::

こちらも詳しくは参考資料をご覧ください
<details>
<summary>参考資料</summary>

[[Ruby on Rails]ランキング表示（合計、平均値）](https://qiita.com/japwork/items/e7675fac18c0e13172a2)
[order | Railsドキュメント](https://railsdoc.com/page/model_order)
[[Rails order]メソッドを使って取得したデータを並び替えよう！](https://pikawaka.com/rails/order)</details>

<h5>2-2ビューファイルの記述</h5>
※「評価点の平均値算出について」で作成したビューファイルの記述でもOK

```:app/views/平均値を表示したいファイル
<% @traders.each do |trader| %>
　<%= trader.name %>
  <%= trader.○○○○ %>
  <%= trader.review_average(trader) %>
<% end %>
```

<h5>完成イメージ</h5>

![top画面１ー１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822721/96f15df8-66a7-6b92-f472-3cc148924b03.png)

:::note info
ポイント：評価する毎に一覧の表記順が変わればOK
:::

<h2>さいごに</h2>

今回PF作成のテーマとしてレビューサイトを作ってみました。
まだ学習中の身なので理解不足・誤りがあったらコメント頂けますと幸いです。m(__)m<ﾖﾛｼｸｵﾈｶﾞｲｼﾏｽ

<h2>感想</h2>

今回はレビュー機能の応用ということで、`平均値の算出`,`並べ替え`を実装しました。
基礎学習時(Bookers)とはまた違った手法や記述式が必要であり、更に過去に全く同じことをした人がいないため
試行錯誤しながらの実装になりました。

また今回の記事には書いていませんが複数権限でのログインも扱っているため、
コントローラやビューファイルの使い分・ルーティングの複雑化など
設計書を作っていないおかげで大変でした。


<h5>参考資料</h5>

[[Ruby on Rails]ランキング表示（合計、平均値）](https://qiita.com/japwork/items/e7675fac18c0e13172a2)
[order | Railsドキュメント](https://railsdoc.com/page/model_order)
[[Rails order]メソッドを使って取得したデータを並び替えよう！](https://pikawaka.com/rails/order)
[[Rails group]メソッドの使い方とは？仕組みを図解で丁寧に解説！](https://pikawaka.com/rails/group#%E9%96%A2%E9%80%A3%E5%85%88%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92group%E3%81%A7%E3%81%BE%E3%81%A8%E3%82%81%E3%81%A6%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)
[[Rails]便利なpluckメソッドの使い方をマスターしよう！](https://pikawaka.com/rails/pluck)