[Rails]星5段階評価実装で躓いた所・メモ 忌まわしきrender様

2024/06/06に公開

前提

https://zenn.dev/goldsaya/articles/2746dd2b886be0
こちらの記事を参考に実装。ありがとうございました!


わからなかった所の自分的解釈、メモを載せていきます
間違ってたら教えてください🥹

books/_form.html.erb
<% if book.id.nil? %>
    <div class="form-group" id="star">
      <%= f.label :star %>
      <%= f.hidden_field :star, id: :review_star, class: 'form-control' %>
      <div id="post_raty"></div>
    </div>

⭐️nil ⇨「何も存在しない」という意味、つまり新規投稿の場合
<% else %>(既存の書籍)の場合、_static_rateファイルが使用される。_後述✍️

😒 { hidden_field...??

🤓 { Hiddenフィールドとは、Webブラウザの画面には表示されないHTMLフォーム項目の事。

画面には表示されず、Webブラウザからリクエストを送信するときに一緒に送信される仕組み.
この値は通常変更されない為、複数のWebページをまたがって情報を保持するために利用される!

 <%= f.hidden_field :star, id: :review_star, class: 'form-control' %>

#メモ
hidden_fieldメソッドの引数は、フォームのモデル属性を表す。この場合『Star』
このコードは星による評価を行うためにhidden_fieldを使用。
今回はいつもみたいに文字を打つわけじゃない、けどフォームを送らないとidとかも送れへん。
やから今回hidden_fieldを使って、(画面に表示されない)フォーム内の他の要素(今回は星を画像を使って5段階評価する)と連動する隠れたフィールドを作成するために使用。

books/_form.html.erb
<% if book.id.nil? %>
    <div class="form-group" id="star">
      <%= f.label :star %>
      <%= f.hidden_field :star, id: :review_star, class: 'form-control' %>
      <div id="post_raty"></div>
    </div>
    <script>
      $(document).on('turbolinks:load', function() {
        let elem = document.querySelector('#post_raty');
        if (elem == null) return;
  
        elem.innerHTML = ""
        let opt = {  
          starOn: "<%= asset_path('star-on.png') %>",
          starOff: "<%= asset_path('star-off.png') %>",
          starHalf: "<%= asset_path('star-half.png') %>",
          scoreName: 'book[star]',
        };
        raty(elem, opt);
      });
    </script>
  <% else %>
    <div class="form-group">
      <%= render "static_rate", book: book %>
    </div>
  <% end %>

既存の書式の場合<% else %>になる。
つまり<%= render "static_rate", book: book %>が適応。

_static.rate.html.erb
<div id="star_<%= book.id %>"></div>
<script>
$(document).on('turbolinks:load', function() {
  let elem = document.querySelector('#star_<%= book.id %>');
  if (elem == null) return;
  
  elem.innerHTML = "";
  let opt = {  
    starOn: "<%= asset_path('star-on.png') %>",
    starOff: "<%= asset_path('star-off.png') %>",
    starHalf: "<%= asset_path('star-half.png') %>",
    score: "<%= book.star %>",
    readOnly: true,
  };
  raty(elem, opt);
});
</script>

POINT🧐

readOnly: true,がこっちには記述されてる!!!
▶︎_static_rate ファイルは、既存の書籍の評価を表示するために使用され、読み取り専用にする
▶︎readOnly パラメータが設定されているため、ユーザーは評価を変更できない😚


私が大苦戦した(いつも)render...

今までrenderを理解するのに何度もメンター質問を使いました。くそ〜
今回は下記を貼り付けたときに起こりました。

books/show.html.erb
<td><%= render "static.rate", book: @book %></td>

何度やってもActionViewError~笑 なんでやね〜ん。
何回もURL違うんか?スペース入ってるん?と治しまくったが一生エラー😇えーん
やけくそになり<%= render "static.rate", book: @book %>を一番下にとりあえず貼り付けて見たんです。そしたらなんとエラーが出ない。(もちろん入れたい場所ではなかった)

考えた結果<td></td>に挟んでるから?と思いAIに聞きました。

当たり前〜くらいの感じで返事きた。笑
私は初めて知りました😌もう絶対忘れません!!!!!!!
他の受講生の方もrenderで引数渡してたけどそもそもeachメソッドの中だったからエラー出た!や、場所変えたら行けた!とおっしゃてたので躓きやすいのか?それにしても私は毎回引っかかってる(笑えない)
(このあとシンプルに"static.rate",が"static_rate",になってて数時間悩まされたのは別の話)

Discussion