[Rails]class_nameオプション
昨日書いたコメント機能について、
class_nameオプションを使えば、task.task_comments
など冗長な部分を
task.comments
とシンプルに書くことができると教わったのでそれをまとめます!
class_nameオプションとは
class_nameオプションとは、RailsのActive Recordでモデルの関連を設定するときに使用できるオプション。
モデル内で使用できる。私たちが作成したモデルの親クラスである、Active Recordが持ってるオプションなので、我々が作成したモデルでもこの機能を使用できる。
冗長な変数名を防ぐだけでなく、関連名(アソシエーション名)がモデル名と一致しない時も、class_nameオプションを使用する。
(Railsは、アソシエーション名を元に、関連するモデルを自動で探す)
使い方
現在のTaskモデル↓
class Task < ApplicationRecord
# :task_comments がアソシエーション名
has_many :task_comments, dependent: :destroy
end
:task_comments
がアソシエーション名。
これでTaskモデルに、Task_commentモデルを関連付けてる。
「has_many」部分からTaskモデルに対して、Task_commentモデルが1:N になるようにしている。
(1個のTaskに対して、コメントは沢山ある)
class_nameオプションを使うと
class Task < ApplicationRecord
# アソシエーション名は :comments
has_many :comments, class_name: "TaskComment", dependent: :destroy
end
アソシエーション名が :comments
に変更される。
class_name: "TaskComment"
を書いてるので、アソシエーション名がモデル名と一致していない :comments
でも、Task_commentモデルと関連付けることができる。
昨日書いたビューはどう変わる?
アソシエーション名が :comments
になったことで、下記に変更される。
<div class="index-results">
<div class="index-card">
<div class="index-header">
<ul>
<b>コメント件数:<%= @task.comments.count %></b>
<hr size="10">
<p></p>
<!-- コメント表示 -->
<% @task.comments.each do |task_comment| %>
<li class="comment">
<div class="comment-container">
<div class="comment-image">
<%= link_to user_path(@task.user) do %>
<% if task_comment.user.image.attached? %>
<%= image_tag task_comment.user.image, alt: "#{task_comment.user.name}のプロフィール画像", class: "profile-image" %>
<% else %>
<%= image_tag "no_image.jpg", alt: "デフォルトプロフィール画像", class: "profile-image" %>
<% end %>
<% end %>
</div>
<div class="comment-content">
<p class="comment-text"><%= task_comment.comment %></p>
<span class="task-meta">
<%= task_comment.user.name %>
<%= task_comment.created_at.in_time_zone('Tokyo').strftime('%m月%d日 %H:%M') %>
<% if task_comment.user == current_user %>
<%= link_to "削除", task_task_comment_path(task_comment.task, task_comment), method: :delete %>
<% end %>
</span>
</div>
<br>
</div>
</li>
<hr size="10">
<% end %>
<!-- コメント投稿フォーム -->
<%= form_with model:[@task, @task_comment] do |f| %>
<%= f.text_area :comment, placeholder: "コメントを入力", class: "form-input-comment" %>
<%= button_tag(type: 'submit', class: 'submit-btn') do %>
<i class="fa-solid fa-paper-plane"></i>
<% end %>
<% end %>
</ul>
</div>
</div>
</div>
具体的には・・・
@task.task_comments
→ @task.comments
になる。(2行目、5行目)
Discussion