⭐️JavascriptのAmbiguous matchエラー

コメント一覧の幅が広くなってしまっていたエラーについて

Image from Gyazo

上記を検証してみた結果、
Ambiguous match, found 2 elements matching visible css "#js-table-comment"
☝️要素(idやclassなど)が重複しているため起きたエラーが発生し、 見本の成果物と自身のHTMLを検証ツールを使って調査してみたら、

・見本

Image from Gyazo

・自身のHTML

Image from Gyazo

このように<body></body>の中に

<!-- コメントエリア -->
<tr id='comment-<%= comment.id %>'>
  <td style="width: 60px">
    <%= image_tag 'sample.jpg', class: 'rounded-circle', size: '50x50' %>
  </td>
  <td>
    <h3 class="small"><%= comment.user.decorate.full_name %></h3>
    <div id="js-comment-<%= comment.id %>">
      <%= simple_format(comment.body) %>
    </div>
    <div id='js-textarea-comment-box-<%= comment.id %>' style="display: none;">
      <textarea id='js-textarea-comment-<%= comment.id %>' class="form-control mb-1"><%= comment.body %></textarea>
      <button class="btn btn-light js-button-edit-comment-cancel" data-comment-id="<%= comment.id %>">キャンセル</button>
      <button class="btn btn-success js-button-comment-update" data-comment-id="<%= comment.id %>">更新</button>
    </div>
  </td>
 
  <% if current_user.own?(comment) %>
    <td class="action">
      <ul class="list-inline justify-content-center" style="float: right;">
        <li class="list-inline-item">
          <a href="#" class='js-edit-comment-button' data-comment-id="<%= comment.id %>">
            <%= icon 'fa', 'pen' %>
          </a>
        </li>
        <li class="list-inline-item">
          <a href="#" class='js-delete-comment-button' data-comment-id="<%= comment.id %>">
            <%= icon 'fas', 'trash' %>
          </a>
        </li>
      </ul>
    </td>
  <% end %>
</tr>

上記(コメント)が 見本では2つ格納されているのに対して、自身のコードでは1つしか格納されていない事が判明。

色々と試してみたが、結果おそらく

<% @comments.each do |comment| %>
  <%= render partial: 'comments/comment', locals: { comment: comment } %>
<% end %>  

このeach文を使っていたことで、コメントが作成されコメント一覧のCSSが適応になるときに、1つずつ

<div class="row">
  <div class="col-lg-8 offset-lg-2">
    <table id="js-table-comment" class="table">
      <%= render @comments %>
    </table>
  </div>
</div>  

が作成されてコメントのCSSがうまく適応されなかったのかと思われます!(色々試しすぎたので、憶測ですが、、、😀)

☀️解決法

・each文を削除し、

<!-- コメントエリア -->
  <%= render 'comments/comments', locals: { comments: @comments } %>

上記のレンダリングが上手くいくように他ファイルの記述を変更。

🟢このエラーに2日くらいかかったので、巻いて行きます!!🔥💪

⭐️フォーム入力時エラー情報を個別表示の確認ポイント

・エラーメッセージ表示部分をformのテンプレートに記載せず、専用のパーシャルが作られていること。

上記、エラーメッセージ表示用にshared配下に_error_messages.html.erbを作成。

<% if object.errors.any? %>
  <div class="alert alert-danger">
    <ul class="mb-0">
      <% object.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
    </ul>
  </div>
<% end %>

<li></li><%= message %>を囲むことによって、エラーメッセージを一文ずつ箇条書きで表示できるようになる。

<li><%= message %></li>

🟢課題をこなしているうちに何となくデータベースの中の情報の取り出し方であったり、ルーティング、コントローラー、ビューの動きが段々と分かってきたので、次の課題からもどんどん知識を増やしていきたい!🔥💪

⭐️掲示板作成機能の確認ポイント

・モデルに```has_many :boards``` 
を設定することで、userオブジェクトで```boards```というメソッドが使えるようになる。  
  

```@board = current_user.boards.build(board_params)```  
  
```current_user.boards.new``` 
 
と実行することで、 
user_idを登録したboardオブジェクトを初期化できます。  
また、newの引数にパラメータを渡すことで入力フォームから渡ってきた情報のオブジェクトが作成できます。  
  
  
このように、アソシエーションで関連したオブジェクトを初期化する際は、通常の初期化と区別して  
```new```  
ではなく 
```build``` 
と記載することがあるらしい。  
  
ちなみに、```build```は```new```のエイリアス(別名)のため、どちらで記載しても挙動は変わらない。  
  

・**開発現場では上記の記法は当たり前のように使われている**そうなので、この記法に慣れるように今後の課題で意識して取り組むようにしよう!  
  

・フォームのテキストエリアの入力幅は**style**で指定するのではなく、 
```rows:```  
で設定すること 
styleは個別のHTMLに直接記載しせずに、cssファイルから適用させる形式の方が管理しやすいため  
  
```
# BAD styleで高さを指定して、入力幅を設定している
<%= f.text_area :body, class: 'form-control', style: 'height: 200px', row: 10 %>

# GOOD styleを使用せずに、rows:オプションで入力幅を設定している
<%= f.text_area :body, class: 'form-control', rows: 10 %>
```
 

⭐️掲示板の一覧機能の作成

gem fakerを使うことによって、簡単にダミーデータを作る事ができ、開発する際は事前にダミーデータを使ってアプリケーションの動作を確認する事が一般的だそうなので、今後fakerのいろんなデータを使ってポートフォリオを作る際に生かしていきたい!

・今回でseedファイルが何の為に存在しているのかが分かった。笑

N+1問題とは

🟢必要以上に SQL が走るせいでパフォーマンスが低下する問題

🟢1対Nの場合

コントローラで @articles を取得する際に

@articles = Article.all.includes(:user)
にすると

SELECT 'article'.* FROM 'articles'

SELECT 'users'.* FROM 'users' WHERE 'users'.'id' IN (1, 2)

の2つの SQL が発行されるだけになり、N+1 問題が解決する。

✅必要以上にSQLを動かさないで、アプリケーションを重くさせないように気をつけながら開発することが大切!

⭐️フラッシュメッセージの設定の確認ポイント

application_controller.rbに以下の設定を追加すると、 デフォルトのalertnotice以外で、Bootstrapに用意されているスタイルのフラッシュを定義できる。

add_flash_types :success, :info, :warning, :danger

https://api.rubyonrails.org/classes/ActionController/Flash/ClassMethods.html
https://qiita.com/Yama-to/items/4d19a714d8bf5bfbabdd

・また、上記の設定を行うことでControllerのredirectをフラッシュメッセージを含めて1行で記載できる。

# BEFORE
redirect_to login_path, flash: { success: 'hoge' }

# AFTER
redirect_to login_path, success: 'hoge'

↑こちらの方が記述量を減らせるので、一行で書けるものは一行で書いていくようにしていこう❗️

プロの進め方
1 . フラッシュの定義を追加する
2 . ログイン、ログアウト時にフラッシュメッセージを表示する
3 . ユーザー作成時にフラッシュメッセージを表示する
4 . フラッシュメッセージの表示をViewに追加する
5 . フラッシュメッセージの翻訳定義を追加する

◉参考記事https://runteq.jp/curriculum_general_users/674/curriculum_chapters/115/curriculum_chapter_point

✅総括 課題6は秒で終わったので、課題4で時間かかった分取り戻していく!🔥💪

⭐️i18nによる日本語化対応の確認ポイント

・gem 'rails-i18n'を導入することで、gem内部の下記の一般的なメッセージについての日本語での国際化設定ファイルを参照するようになる。
https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml

・Modelに紐付くform_withのlabelでは、Railsが下記の定義を読み込んで適用する。
Image from Gyazo

<%= form_with model: @user, local: true do |f| %>
  <div class="form-group">
    <%= f.label :last_name %>
    <%#= f.label :last_name,  User.human_attribute_name(:last_name) %>
    <%# Railsが適用するのでi18n部分を記載する必要がない %>
<% end %>

・ユーザーログイン(app/view/user_session)でのViewファイルでは、labelに対してi18nの記載を追加する必要がある。

✅総括 i18nによる日本語化対応のファイルの書き方やそれを反映させるやり方について学べたので、次回日本語化にする実装の時に生かしていこう!🔥💪