random_user_0891
random_user_0891

Reputation: 2051

Rails redirect after destroy action

I have a model named Group which has_many Posts and each Post has_many Comments. I can navigate to a group, create a post and then create a comment under that post. My issue is when I try and delete a comment I receive the below error about the redirect (the comment is deleted the redirect just doesn't happen).

undefined method `id' for nil:NilClass

this is the line in my destry action it does not like, which is weird because my update action has the same redirect and that works fine.

  format.html { redirect_to group_post_url(group_id: @group.id, id: @post), notice: 'Comment was successfully destroyed.' }

I tried adding [:destroy] onto the set_post before_action thinking that it might need that but no luck.

here's some of my routes

        group_posts GET    /groups/:group_id/posts(.:format)                            posts#index
                    POST   /groups/:group_id/posts(.:format)                            posts#create
     new_group_post GET    /groups/:group_id/posts/new(.:format)                        posts#new
    edit_group_post GET    /groups/:group_id/posts/:id/edit(.:format)                   posts#edit
         group_post GET    /groups/:group_id/posts/:id(.:format)                        posts#show
                    PATCH  /groups/:group_id/posts/:id(.:format)                        posts#update
                    PUT    /groups/:group_id/posts/:id(.:format)                        posts#update
                    DELETE /groups/:group_id/posts/:id(.:format)                        posts#destroy
             groups GET    /groups(.:format)                                            groups#index
                    POST   /groups(.:format)                                            groups#create

here's my comments_controller.rb

class CommentsController < ApplicationController

  before_action :set_group, only: [:index, :show, :new, :edit, :create, :update]
  before_action :set_post, only: [:index, :show, :new, :edit, :create, :update]
  before_action :set_comment, only: [:show, :edit, :update, :destroy]

  # GET /posts/:post_id/comments
  def index
    @comments = @post.comments.order(created_at: :desc)
  end

  def show
  end

  # GET /posts/:post_id/comments/new
  def new
    @comment = @post.comments.new
  end

  # # GET /posts/:post_id/comments/edit
  # def edit
  # end

  # POST /posts/:post_id/comments
  def create
    # inserts current_user into the comments foriegn key for user_id.
    @comment = @post.comments.new(comment_params.merge(user_id: current_user.id))

    respond_to do |format|
      if @comment.save
        format.html { redirect_to group_post_url(group_id: @group.id, id: @post), notice: 'Comment was successfully created.' }
        format.json { render :show, status: :created, location: @comment }
      else
        format.html { render :new }
        format.json { render json: @comment.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /posts/:post_id/comments/:id
  def update
    respond_to do |format|
      if @post.comments.update(comment_params)
        format.html { redirect_to group_post_url(group_id: @group.id, id: @post), notice: 'Comment was successfully updated.' }
        format.json { render :show, status: :ok, location: @comment }
      else
        format.html { render :edit }
        format.json { render json: @comment.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /posts/:post_id/comments/:id
  def destroy
    @comment.destroy
    respond_to do |format|
      format.html { redirect_to group_post_url(group_id: @group.id, id: @post), notice: 'Comment was successfully destroyed.' }
      format.json { head :no_content }
    end
  end


  ###################
  # private methods
  ###################
  private
    # Use callbacks to share common setup or constraints between actions.
    def set_comment
      @comment = Comment.find(params[:id])
    end

    def set_post
      @post = Post.find(params[:post_id])
    end

    def set_group
      @group = Group.find(params[:group_id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def comment_params
      params.require(:comment).permit(:content, :post_id, :user_id)
    end
end

Upvotes: 0

Views: 455

Answers (1)

Anthony L
Anthony L

Reputation: 2169

If you'd like to reference the @group instance variable, you should add :destroy to the before_action set_group callback:

before_action :set_group, only: [:index, :show, :new, :edit, :create, :update, :destroy]

You should also add :destroy to the before_action set_post callback as well

Upvotes: 2

Related Questions