How to fix nil:NilClass error in polymorphic-associations? - ruby-on-rails

This is my comment controller code
private
def set_commentable
#commentable = Question.find(params[:question_id])
#commentable = Comment.find(params[:comment_id])
end
I've tried but i'm getting below error, I hope I did error in passing of comment id
undefined method `set_comment' for #<CommentsController:0xb34e3348>

Add this in your comments controller
def set_comment
#comment = Comment.find(params[:id])
end

Since you don't have set_commentable inside your CommentsController your are getting undefined method error:
before_action :set_comment, only: [:show, :edit, :update, :destroy, :create]
private
def set_comment
#commentable = Comment.find(params[:id])
end

Related

Undefined method `upvote_by' for nil:NilClass

There are the same problem, but answers are not good for my code. Error is still there.
I reinstall gem, try different versions, and I think add methods in before_action properly and problem is still there.
class ArticlesController < ApplicationController
helper_method :sort_column, :sort_direction
before_action :authenticate_user!, except: [:index, :show, :like, :unlike]
before_action only: [:like, :unlike]
...
def like
#article.upvote_by current_user
redirect_to articles_path
end
def unlike
#article.downvote_by current_user
redirect_to articles_path
end
...
And html
<%= link_to "Like", like_article_path(article), class: 'like_url', method: :put %>
When click on it.
undefined method `upvote_by' for nil:NilClass
You need to find your Article first:
def like
#article = Article.find(params[:id])
# ...
end
def unlike
#article = Article.find(params[:id])
# ...
end
You can also extract article finding to before_action
before_action :find_article, only: %i[like unlike] # whatever you please
# ...
private
def find_article
#article = Article.find(params[:id])
end

Devise before_action explanation

I am having trouble understanding this line that gets automatically generated in the controller when I install Devise:
before_action :set_post, only: [:show, :edit, :update, :destroy]
I tried reading the documentation but I am unable to make sense of what it does. For example what does the :set_post symbol do? What is it part of?
Any explanations or resources where I can go for further reading would be appreciated.
Suppose you have a controller like this:
class PostController < ApplicationController
def index
#posts = Post.all
end
def show
#post = Post.find(params[:id])
end
def edit
#post = Post.find(params[:id])
end
end
You see that in show and edit actions there is the same code, you're breaking the DRY principle, so to avoid code repetitions you set an action (method):
def set_post
#post = Post.find(params[:id])
end
that will be performed before the actions that require that same code:
before_action :set_post, only: [:show, :edit, :update, :destroy]
In the end you'll have a controller like this:
class PostController < ApplicationController
def index
#posts = Post.all
end
def show
end
def edit
end
private
def set_post
#post = Post.find(params[:id])
end
end
:set_post - a method at the end of the controller.
The device does not have anything to do with

Couldn't find Comment without an ID - polymorphic associations

The error appears when I try to submit a comment. - ActiveRecord::RecordNotFound in CommentsController#index - I followed this and this tutorial
the URL is:
.../articles/1/comments
comments_controller
class CommentsController < ApplicationController
before_action :set_comment
before_action :signed_in_user, only: [:new]
def index
#commentable = load_commentable
#comments = #commentable.comments
end
...
def create
#comment = #commentable.comments.new(comment_params)
#comment.user = current_user
if #comment.save
redirect_to #comment, notice: "Comment created."
else
render :new
end
end
....
private
def load_commentable
resource, id = request.path.split('/')[1, 2]
#commentable = resource.singularize.classify.constantize.find(id)
end
def set_comment
#comment = Comment.find(params[:id])
end
....
Full trace:
As per the stacktrace, error is appearing on set_comment method.
You must be having a callback before_action on set_comment which should not be there for index action. You should restrict that to only relevant actions.
For example:
before_action :set_comment, only: [:show, :edit, :update, :destroy]
So that this callback would only be invoked for show, edit, update and destroy actions.
UPDATE
Currently callback is set as before_action :set_comment without any restrictions so it will be invoked before each and every action. So, update it as suggested above.

Update route in rails doesn't respond well to after_action?

class FrogsController < ApplicationController
before_action :find_frog, only: [:edit, :update, :show, :destroy]
after_action :redirect_home, only: [:update, :create, :destroy]
def index
#frogs = Frog.all
end
def new
#ponds = Pond.all
#frog = Frog.new
end
def create
#frog = Frog.create(frog_params)
end
def edit
#ponds = Pond.all
end
def update
#frog.update_attributes(frog_params)
end
def show
end
def destroy
#frog.destroy
end
private
def find_frog
#frog = Frog.find(params[:id])
end
def frog_params
params.require(:frog).permit(:name, :color, :pond_id)
end
def redirect_home
redirect_to frogs_path
end
end
Hi all. I was wondering if someone could explain to me why the update route in rails can't take my after_action of redirecting (custom made method on the bottom) it home. The error that I get when i include update in the after_action is "Missing template frogs/update".
This is going to cause me to manually add a redirect_to frogs_path inside the update method.
thanks!
The after_action callback is triggered after the action has run its course. You cannot use it to render or redirect. Do that within the action itself by calling the method:
def update
...
redirect_home
end

refactoring generated action code in the controller

If I generate a scaffold I get the standard actions index, new, show, create .... all of which contain a line e.g. like
#comment = Comment.find(params[:id])
Does it make sense to put this line in a seperate method into the controller like
def load
#comment = Comment.find(params[:id])
end
Is this an advantage? Thx for your time
Yes to the separate method, and also yes to using a before_filter.
class CommentsController < ApplicationController
# Whitelist your before_filter like this. Or you can blacklist it with :except => []
before_filter :load_comment, :only => [:edit, :update, :destroy, :show]
def show
end
def index
#comments = Comment.all
end
def new
#comment = Comment.new
end
# etc ...
protected
def load_comment
#comment = Comment.find(params[:id])
end
end

Resources