質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.42%
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

357閲覧

【Ruby On Rails, Raty.js】投稿一覧ページでレビューの平均点を出力したい。

sato_sato

総合スコア8

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2023/05/23 14:23

編集2023/05/24 13:54

実現したいこと

  • 新規投稿時(reviews/new)に入力した5種類のレビュー項目の平均点を、レビュー一覧ページ(homes/top)で出力させたいです。

【↓ 新規投稿画面のレビュー5項目 ↓】
イメージ説明
【↓ レビュー投稿一覧ページの平均点箇所(ワイヤフレーム図) ↓】
イメージ説明

前提

Railsでレビュー投稿サイトを作成しております。
現在、Raty.jsを導入し、レビュー投稿(reviews/new)・投稿一覧ページ(homes/top)を作成中です。

発生している問題・エラーメッセージ

  • 「実現したいこと」で述べておりましたが、レビュー新規投稿する際に予め設定している5項目の評価を入力し、投稿するようにしています。
  • 投稿一覧ページでその5項目の平均点を出力させたいのですが、1つの評価の点数のみ表示されます。
  • 平均点の左側に星マークを出したいのですが、数字のみ表示されます。(画像では「:4.0」のみ)

下記画像
イメージ説明

該当のソースコード

schema.rb

1 create_table "reviews", force: :cascade do |t| 2 t.integer "user_id", null: false 3 t.string "title", default: "", null: false 4 t.string "body", default: "", null: false 5 t.boolean "review_type", default: true, null: false 6 t.datetime "created_at", precision: 6, null: false 7 t.datetime "updated_at", precision: 6, null: false 8 t.index ["user_id"], name: "index_reviews_on_user_id" 9 end 10 11 create_table "stars", force: :cascade do |t| 12 t.integer "review_id", null: false 13 t.string "name", default: "", null: false 14 t.float "score", default: 0.0, null: false 15 t.datetime "created_at", precision: 6, null: false 16 t.datetime "updated_at", precision: 6, null: false 17 t.index ["review_id"], name: "index_stars_on_review_id" 18 end

reviews_controller.rb

1 def new 2 @review = Review.new 3 # raty.js用のフォーム 4 @star = Star.new 5 end 6 7 def create 8 @review = Review.new(review_params) 9 if @review.save! 10 # @review.star.create(name: "ゲレンデ", score: params[:star][:star2]) 11 @review.stars.create({ 12 { name: "ゲレンデ", score: params[:star][:star] }, 13 { name: "コストパフォーマンス", score: params[:star][:star2] }, 14 { name: "接客・サービス", score: params[:star][:star3] }, 15 { name: "設備の充実", score: params[:star][:star4] }, 16 { name: "周辺設備", score: params[:star][:star5] }, 17 }) 18 redirect_to homes_top_path 19 else 20 render :new 21 end 22 end

reviews/new.html.erb(レビュー新規投稿ページ)

1 <tr> 2 <th>評価</th> 3 <td> 4 ゲレンデ<div id="post_raty"></div> 5 <script> 6 var elem = document.getElementById('post_raty'); 7 var opt = { 8 starOn: "<%= asset_path('star-on.png') %>", 9 starOff: "<%= asset_path('star-off.png') %>", 10 starHalf: "<%= asset_path('star-half.png') %>", 11 half: true, 12 scoreName: 'star[star]', 13 }; 14 raty(elem,opt); 15 </script> 16 17 コストパフォーマンス<div id="post_raty2"></div> 18 <script> 19 var elem = document.getElementById('post_raty2'); 20 var opt = { 21 starOn: "<%= asset_path('star-on.png') %>", 22 starOff: "<%= asset_path('star-off.png') %>", 23 starHalf: "<%= asset_path('star-half.png') %>", 24 half: true, 25 scoreName: 'star[star2]', 26 }; 27 raty(elem,opt); 28 </script> 29 30 接客・サービス<div id="post_raty3"></div> 31 <script> 32 var elem = document.getElementById('post_raty3'); 33 var opt = { 34 starOn: "<%= asset_path('star-on.png') %>", 35 starOff: "<%= asset_path('star-off.png') %>", 36 starHalf: "<%= asset_path('star-half.png') %>", 37 half: true, 38 scoreName: 'star[star3]', 39 }; 40 raty(elem,opt); 41 </script> 42 43 設備の充実<div id="post_raty4"></div> 44 <script> 45 var elem = document.getElementById('post_raty4'); 46 var opt = { 47 starOn: "<%= asset_path('star-on.png') %>", 48 starOff: "<%= asset_path('star-off.png') %>", 49 starHalf: "<%= asset_path('star-half.png') %>", 50 half: true, 51 scoreName: 'star[star4]', 52 }; 53 raty(elem,opt); 54 </script> 55 56 周辺設備<div id="post_raty5"></div> 57 <script> 58 var elem = document.getElementById('post_raty5'); 59 var opt = { 60 starOn: "<%= asset_path('star-on.png') %>", 61 starOff: "<%= asset_path('star-off.png') %>", 62 starHalf: "<%= asset_path('star-half.png') %>", 63 half: true, 64 scoreName: 'star[star5]', 65 }; 66 raty(elem,opt); 67 </script> 68 </td> 69 </tr>

homes/top.html.erb

1 <% @reviews.each do |review| %> 2 <div> 3 <!-- get_user_imageにundefined methodが出る --> 4 <!-- 複数形に対して画像の --> 5 <%= image_tag review.user.get_user_image(100,100) %> 6 <%= review.user.name %> 7 </div> 8 9 <!-- 投稿画像が表示されない(ユーザー画像が取得されている?) --> 10 <%= image_tag review.get_review_image(200,200) %> 11 12 <!-- レビューの平均を出したい --> 13 <!-- 参考サイト:https://qiita.com/kcl215/items/e226ac58d14360fd1b8e --> 14 <div class="starrate"> 15 <%# 平均点を算出し、round関数で切り上げ %> 16 <%=@all_score %>:<%= review.stars.average(:score).to_f.round(1) %> 17 <%# 評価数を星に置き換える %> 18 <div class="average-review-rating" data-score=<%= review.stars.average(:score) %>></div> 19 <%# jquery発火イベントを記載%> 20 <script> 21 $('#star').empty(); 22 $('.average-review-rating').raty({ 23 readOnly: true, 24 starOn: "<%= asset_path('star-on.png') %>", 25 starOff: "<%= asset_path('star-off.png') %>", 26 starHalf: "<%= asset_path('star-half.png') %>", 27 score: function() { 28 return $(this).attr('data-score') 29 } 30 }); 31 </script> 32 </div> 33 34 <%= review.title %><br> 35 <%= review.body %> 36 <% end %>

試したこと

  • rails cでStar.all(星評価用のテーブル)でTerminalを見たところ、5項目の内、最後の項目のみが送信されていました。

(「周辺設備」のみのデータが送られており、その他の4項目は未送信)

投稿時点でデータが送られていないと思い、controllerの記述を見直しましたが修正するまで漕ぎつけておりません、、、

  • reviews_controllerのレビュー評価の5項目を1つ1つ{}で囲い、個包装したところ、引数エラーが発生。

イメージ説明

viewページでの修正が必要?

補足情報(FW/ツールのバージョンなど)

Rails 6.1.7.3
raty.js 4.1.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

とりあえず「(「周辺設備」のみのデータが送られており、その他の4項目は未送信)」ここの問題を

@review.stars.create({ name: "ゲレンデ", score: params[:star][:star], name: "コストパフォーマンス", score: params[:star][:star2], name: "接客・サービス", score: params[:star][:star3], name: "設備の充実", score: params[:star][:star4], name: "周辺設備", score: params[:star][:star5], })

create が1回だけなので、一つだけ作れらます。
引数のHashのなかにkeyとして :name, :score が5回ずつでてますが、同じ keyなので上書きされて結果最後のものだけが有効になってます。

投稿2023/05/23 22:48

winterboum

総合スコア23464

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sato_sato

2023/05/24 14:05

コメント頂きありがとうございます。「試したこと」を1つ追記いたしました。 「引数のHashのなかにkeyとして :name, :score が5回ずつでてますが、同じ key」といったところで、ご質問失礼します。 例えば2つ目の"コストパフォーマンス"であれば name: "コストパフォーマンス", score: params[:star][:star2] 下記のようにカラムを追加するようなイメージでよろしいでしょうか? name2: "コストパフォーマンス", score2: params[:star][:star2]
winterboum

2023/05/24 20:12

model のcodeがないのでschemaとcontrollerからのエスパーですが、1:多 ですよね? でしたら違います。 createを5回やってください。
sato_sato

2023/05/25 23:16 編集

def create @review = Review.new(review_params) @review.stars.build(name: "ゲレンデ", score: params[:star][:star]) のようにcontroller内で子要素として置き、 viewページ内でscriptをeach文で回して一位性を持たせたら解決しました。(一覧ページで評価平均値がそれぞれ出力された) ご対応いただき、ありがとうございました。
winterboum

2023/05/25 23:22

Bon! view と review_params の書き方によって @review = Review.new(review_params) だけで 子要素も一度に作る方法もありますので、 勉強してみてください。
sato_sato

2023/05/28 01:18

なるほど! その方がcontroller内の記述が見やすくなりそうですね... 参考になりました! ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.42%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問