th_9plus
@th_9plus (たかちゃん)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Ruby on rails コメント削除機能

コメント機能実装中です。
自分がコメントしたコメントを他のユーザーも削除できてしまう状態になっています。
自分の書いたコメントしか削除できないようにしたいのですが
<% if c.user %>
にしてみましたが制限をかける事ができないです。
他にも<% if c.user_id %>
もしてみましたが変わらずでした。教えて頂きたいです。
よろしくお願い致します。

posts/show.html
<div class="comment-wrapper">
      <p>コメント一覧</p>
      <% @comments.each do |c| %>
        <div class="user-comment">
          <% unless c.user.blank? %>
           <img src="<%= "/user_images/#{c.user.image_name}" %>">
          <% end %>
          <%= c.user.name unless c.user.blank? %>
          <br />
          <%= c.content %>
          <% if c.user %>
           <%= link_to "削除", comment_path(c), method: :delete, class: "comment-menus" %>
          <% end %>
        </div>
        <br />
class PostsController < ApplicationController
    before_action :authenticate_user
    before_action :ensure_correct_user, {only: [:edit, :update, :destroy]}

  def index
    @posts = Post.all.order(created_at: :desc)
  end

  def show
    @post = Post.find_by(id: params[:id])
    @user = @post.user
    @post = Post.find(params[:id])
    @comments = @post.comments
    @comment = Comment.new
  end

  def new
    @post = Post.new
  end

  def create
    @post = Post.new(
      content: params[:content],
      user_id: @current_user.id,
     )
     if params[:post].present?
      @post.video = params[:post][:video]
      print params
     end
    if @post.save
     flash[:notice] = "投稿を作成しました"
     redirect_to("/posts/index")
    else
     render("posts/new")
    end
  end

 def edit
   @post = Post.find_by(id: params[:id])
 end

 def update
    @post = Post.find_by(id: params[:id])
    @post.content = params[:content]
   if @post.save
    flash[:notice] = "投稿を編集しました"
    redirect_to("/posts/index")
   else
    render("posts/edit")
   end
 end

 def destroy
   @post = Post.find_by(id: params[:id])
   @post.destroy
   flash[:notice] = "投稿を削除しました"
   redirect_to("/posts/index")
 end

 def ensure_correct_user
     @post = Post.find_by(id: params[:id])
     if @post.user_id != @current_user.id
       flash[:notice] = "権限がありません"
       redirect_to("/posts/index")
     end
 end
end
0

1Answer

view で制限すると,直接アクセスしたときにまだ可能になってしまうので,
コントローラ側で制限した方が良いかと思います.

if c.user ですと,c (=コメント) にユーザが存在する場合ですので,通常は常に真になるかと思います.
例えば,今現在ログインしているユーザと,コメントのユーザが等しい場合という条件を入れるのが良いと思います.

if login_user == c.user
0Like

Comments

  1. @th_9plus

    Questioner

    viewの方では
    <% if c.user_id == current_user.id %>
    これで制限できるようになりましたが
    直接アクセスしたときにまだ可能になってしまう> コントローラーのdestroyにどのように追加すれば良いでしょうか?
  2. そうですね.雰囲気で書きますと

    ```ruby
    def destroy
    unless c.user_id == cuirrent_user.id
    # 何らかのメッセージ?
    end
    c.destroy # 元の処理
    end
    ```

    みたいな感じでどうでしょうか?
  3. @th_9plus

    Questioner

    こちらでうまくいきました!
    ありがとうございます!

    ```
    def destroy
    unless c.user_id == cuirrent_user.id
    flash[:notice] = "コメントを削除しました"
    end
    @post = Post.find_by(id: params[:id])
    @post.destroy
    flash[:notice] = "投稿を削除しました"
    redirect_to("/posts/index")
    end
    ```
  4. @th_9plus

    Questioner

    すいません
    コメントの削除はできるのですが
    普通の投稿を削除した時に定義されていないエラーが出るようになってしまったのですがどの変更すれば良いでしょうか?
    ```
    NameError in PostsController#destroy
    undefined local variable or method `c' for #<PostsController:0x00007fc9403b6670>
    Extracted source (around line #54):
    52
    53
    54
    55
    56
    57


    def destroy
    unless c.user_id == cuirrent_user.id
    flash[:notice] = "コメントを削除しました"
    end
    @post = Post.find_by(id: params[:id])
    ```
  5. @th_9plus

    Questioner

    またunless @commnts.user_id == cuirrent_user.id に変更した場合はnilのエラーが出ます。
    ```
    NoMethodError in PostsController#destroy
    undefined method `user_id' for nil:NilClass
    Extracted source (around line #54):
    52
    53
    54
    55
    56
    57


    def destroy
    unless @commnts.user_id == cuirrent_user.id
    flash[:notice] = "コメントを削除しました"
    end
    @post = Post.find_by(id: params[:id])
    ```
  6. @th_9plus

    Questioner

    デバックしたところnilの確認はできました。
    ```
    def destroy
    p "=================="
    p @comments
    p "==================="
    unless @commnts.user_id == cuirrent_user.id
    flash[:notice] = "コメントを削除しました"
    end
    ```

    "=================="
    nil
    "==================="

Your answer might help someone💌