コメント機能
アプリケーションにコメント機能を追加します。ログインしているユーザーがコメントできるようにします。
scaffold
コメントのscaffoldを自動生成します。コメントはUserとPhotoに関連付けます。コンソールで以下のコマンドを実行します。
rails g scaffold comment user_id:integer photo_id:integer body:text
マイグレーションを行います。コンソールで以下のコマンドを実行します。
rake db:migrate
CommentとUserとPhotoの関連付け
app/models/user.rb をエディタで開きます。この行のあとに
has_many :photos
この行を追加します。
has_many :comments
app/models/photo.rb をエディタで開きます。この行のあとに
belongs_to :user
この行を追加します。
has_many :comments
app/models/comment.rb をエディタで開きます。この行のあとに
class Comment < ActiveRecord::Base
この行を追加します。
belongs_to :user
belongs_to :photo
サーバーを起動したターミナルとは別のターミナルで、Railsコンソールを起動します。
rails c
PhotoとCommentが関連付けられているか確認します。まだデータがないので何も取得できませんが、エラーなどが発生しないことを確認します。
Photo.last.comments
UserとCommentが関連付けられているか確認します。まだデータがないので何も取得できませんが、エラーなどが発生しないことを確認します。
User.last.comments
Controllerの修正
app/controllers/photos_controller.rb をエディタで開きます。showアクションを修正して、コメントを表示できるようにします。このコードを
def show
@photo = Photo.includes(:user).find(params[:id])
end
このように変更してください。
def show
@photo = Photo.includes(:user).find(params[:id])
@comments = @photo.comments.includes(:user).all
@comment = @photo.comments.build(user_id: current_user.id) if current_user
end
@comments
にPhotoに関連したコメントを格納します。user_nameの表示を行うため、コメントに関連したUserも取得しておきます。
@comments = @photo.comments.includes(:user).all
@comment
はコメントを新規作成するためのインスタンスです。
@comment = @photo.comments.build(user_id: current_user.id) if current_user
Photoに関連させるため @photo.comments.build
としてインスタンスを生成します。
buildの引数にuser_idを渡して、Userとも関連付けします。
ログインしていない場合はコメントできないため、@commentは不要です。
Viewの修正
app/views/photos/show.html.erb をエディタで開きます。このコードのあとに
<% end %>
</div>
このコードを追加します。
<div>
<% @comments.each do |comment| %>
<div>
<strong><%= comment.user.user_name %></strong>
<br />
<p><%= comment.body %></p>
<% if user_signed_in? && comment.user == current_user %>
<p><%= link_to 'Delete', comment_path(comment), method: :delete %></p>
<% end %>
</div>
<% end %>
<% if user_signed_in? %>
<%= render 'comments/form' %>
<% end %>
</div>
コメントしたユーザーのuser_nameは、commentの関連から取得します。
<strong><%= comment.user.user_name %></strong>
コメントしたユーザーのみ、コメントの削除ができるようにします。
<% if user_signed_in? && comment.user == current_user %>
<p><%= link_to 'Delete', comment_path(comment), method: :delete %></p>
<% end %>
ログインしていないと、コメントできないようにします。
<% if user_signed_in? %>
<%= render 'comments/form' %>
<% end %>
app/views/comments/_form.html.erb をエディタで開きます。これらのコードを削除し
<div class="field">
<%= f.label :user_id %><br>
<%= f.number_field :user_id %>
</div>
<div class="field">
<%= f.label :photo_id %><br>
<%= f.number_field :photo_id %>
</div>
これらのコードを追加します。
<%= f.hidden_field :user_id %>
<%= f.hidden_field :photo_id %>
user_idやphoto_idは表示する必要がないので、hiddenフィールドとして保持します。
サーバーを起動し、コメントできるか確認します。すでにサーバーが起動している場合は、再起動してください。
rails s