Reputation: 2051
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
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