コメント機能
内容
投稿詳細ページでコメント機能を実装する
コメント機能
1. モデルを作成
Commentモデルを作成し、マイグレーションファイルを編集する
ターミナル
% rails g model comment
db/migrate/20XXXXXXXXXXXX_create_comments.rb
t.text :comment t.references :user, null: false, foreign_key: true t.references :post, null: false, foreign_key: true
ターミナル
% rails db:migrate
続いてアソシエーションを記述
app/models/comment.rb
belongs_to :user belongs_to :post
app/models/user.rb
has_many :comments, dependent: :destroy
app/models/post.rb
has_many :comments, dependent: :destroy
2. ルーティングを設定
コメントは投稿に紐付くのでルーティングにネストを利用する
routes.rb
resources :posts, except: :index do resources :comments, only: %i[create destroy] end
※いいね機能の時はネストをresource :likeで記述してよかった
→なぜなら1件の投稿に対していいねは1回しかできないため、idを指定しなくても投稿に関連したいいねを削除できるから
※一方、コメント機能ではresources :commentsとしなければならない
→なぜなら1件の投稿に対してコメントは何回でもでき、それを削除したい場合どのコメントを消すかidを指定しなければならないから
3. コントローラーを作成
commentsコントローラーを作成し、createアクションとdestroyアクションを定義
ターミナル
% rails g controller comments
app/controllers/comments_controller.rb
before_action :post_find, only: %i[create destroy] def create @comment = @post.comments.new(comment_params) if @comment.save redirect_to post_path(@post.id) else @comments = @post.comments.includes(:user) render post_path(@post.id) end end def destroy @comment = @post.comments.find(params[:id]) @comment.destroy redirect_to post_path(@post.id) end private def post_find @post = Post.find(params[:post_id]) end def comment_params params.require(:comment).permit(:comment).merge(user_id: current_user.id) end
4. ビューを編集
投稿詳細ページにコメント投稿フォーム、およびコメント表示欄を作成
app/views/posts/show.html.erb
<%= form_with(model: [@post, @comment], local: true) do |f| %> <%= f.text_area :comment, placeholder: "コメントする", maxlength: "140" %> <%= f.submit "送信" %> <% end %> <% @comments.each do |comment| %> <p> <strong><%= link_to comment.user.nickname, user_path(comment.user.id) %>:</strong> <%= comment.comment %> <strong>[<%= link_to "削除", post_comment_path(post_id: @post.id, id: comment.id), method: :delete, data: {confirm: "コメントを削除してもよろしいですか?"} %>]</strong> </p> <% end %>
5. Postコントローラーを編集
app/controllers/posts_controller.rb
def show @comment = Comment.new @comments = @post.comments.includes(:user) end
6. ビューの微修正
コメント欄に投稿時刻等を記述
時刻の設定には、Railsのapplication.rbという設定ファイルを扱う
config/application.rb
class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 6.0 config.i18n.default_locale = :ja config.time_zone = 'Tokyo'
ja.ymlファイルを作成して、表示する時刻のフォーマットを設定
config/locales/ja.yml
ja: time: formats: default: "%Y/%m/%d %H:%M:%S"
この時刻設定を元に、lメソッドを利用して、表示する時刻へ反映
show.html.erb
<%= l comment.created_at %>
所感
もっとコードを簡潔にかけるかもしれないが、今の私にとってはこれが精一杯
次回
コメント機能の非同期化、もしくは住所登録/検索機能を実装する