Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting undefined method `errors' for nil:NilClass Ruby on Rails Guide

Okay, I've been searching for a question here thats exactly the same as mine and I can't find one, so I'm forced to ask it myself. I'm following the guide on here: http://guides.rubyonrails.org/getting_started.html

I ran into this error saying: "undefined method `errors' for nil:NilClass" for my Edit Article page.

Here is my extracted source:

 <h1>Editing article</h1>
 <%= form_for :article, url: articles_path(@article), method: :patch do |f| %>
   <% if @article.errors.any? %>
     <div id="error_explanation">
       <h2><%= pluralize(@article.errors.count, "error") %> prohibited
            this article from being saved: </h2>

And here is my trace:

app/views/articles/edit.html.erb:4:in block in _app_views_articles_edit_html_erb___778692675__618464548

app/views/articles/edit.html.erb:3:in _app_views_articles_edit_html_erb___778692675__618464548

Here is my action Controller

class ArticlesController < ApplicationController
def new
    @article = Article.new
end

def edit
    @articles = Article.find(params[:id])
end

def create
    @article = Article.new(article_params)

    if @article.save
        redirect_to @article
    else
        render 'new'
    end
end

def show
    @article = Article.find(params[:id])
end

def index
    @articles = Article.all
end

def update
    @article = Article.find(params[:id])

    if @article.update(article_params)
        redirect_to @article
    else
        render 'edit'
    end
end

private
    def article_params
        params.require(:article).permit(:title, :text)
    end


 end

And here is my edit.html.erb

<h1>Editing article</h1>

<%= form_for :article, url: articles_path(@article), method: :patch do |f| %>
  <% if @article.errors.any? %>
    <div id="error_explanation">
  <h2><%= pluralize(@article.errors.count, "error") %> prohibited this article 
        from being saved: </h2>
     <ul>
        <% @article.errors.full_messages.each do |msg| %><li><%= msg %></li>
     <% end %>
     </ul>
     </div>
  <% end %>


  <p>
    <%= f.label :title %><br>
<%= f.text_field :title %>
  </p>

  <p>
<%= f.label :text %><br>
<%= f.text_area :text %>
  </p>

  <p>
<%= f.submit %>
  </p>
<% end %>
like image 618
lgdelacruz Avatar asked Jun 18 '14 19:06

lgdelacruz


3 Answers

Variable Definition

Something you might want to consider, alongside Arup's answer, is the error itself:

"undefined method `errors' for nil:NilClass"

What you're getting back is an exception because you're trying to call a method on a nil class object. As Arup pointed out, this is generally caused by your calling of an @instance_variable without defining it first

I want to highlight the fact that your error says the problem is you have an undefined method for your object. Most would treat the problem as your method is undefined for some reason; in reality the problem is you don't have the object defined.

--

Fix

The way to fix the error, as pointed out by Arup is to reference the @instance variable that's defined in the edit method, like this:

#app/controllers/articles_controller.rb
Class ArticlesController < ApplicationController
   def edit
       @article = Article.find params[:id]
   end
end

#app/views/articles/edit.html.erb
<%= @article.errors %>

Something else you will want to consider is the following:

#app/views/articles/edit.html.erb
<%= form_for @article do |f| %>
   # ...
<% end %>
like image 100
Richard Peck Avatar answered Nov 20 '22 05:11

Richard Peck


Yes, you have a typo with the instance variable.

<% if @article.errors.any? %>

should be

<% if @articles.errors.any? %>

Because inside the controller action #edit, you have defined @articles not @article. But it should be named @article since it's a single article. Thus keep <% if @article.errors.any? %> as it is, change the #edit method as

def edit
    @article = Article.find(params[:id])
end

Remember instance variables returns nil, if you attempt to use it before defining it in Ruby. The same happened in your case. You defined @articles, but used @article, which was not defined by you before attempting to use it, thus returns nil. And nil.errors throws the error as you see.

like image 37
Arup Rakshit Avatar answered Nov 20 '22 06:11

Arup Rakshit


The problem is that @article is nil (null)

In your controller, edit the new action, so it looks like this:

def new
  @article = Article.new
end

Refresh the web page, and there is no more error.

like image 3
Sterling Diaz Avatar answered Nov 20 '22 05:11

Sterling Diaz