user650261
user650261

Reputation: 2265

NoMethodError in Articles#edit in Ruby on Rails tutorial section 5.11

Get this out of the way: Ubuntu 12.04 64 bit, Ruby 2.0.0, Rails 4.1.0

I'm trying to follow the official Ruby On Rails Tutorial ( http://guides.rubyonrails.org/getting_started.html ) but I am getting stuck at section 5.11. I have seen people having trouble with 5.12 but not 5.11, so I figured I should ask.

This is the part where they teach you how to edit a file. Now, I have, as they said, for my edit.html.erb file:

<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 %>

<%= link_to 'Back', articles_path %>

When I try to edit a file, though, I get the following error:

oMethodError in Articles#edit
Showing /home/aespielberg/RoR/blog/app/views/articles/edit.html.erb where line #4 raised:

undefined method `errors' for nil:NilClass
Extracted source (around line #4):

  <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>

Rails.root: /home/aespielberg/RoR/blog

Application Trace | Framework Trace | Full Trace
app/views/articles/edit.html.erb:4:in `block in _app_views_articles_edit_html_erb__4315770151411025849_69984046087300'
app/views/articles/edit.html.erb:3:in `_app_views_articles_edit_html_erb__4315770151411025849_69984046087300'

Now, I'm not sure why this is, because Article inherits:

class Article < ActiveRecord::Base
  validates :title, presence: true,
                    length: { minimum: 5 }
end

Which, as far as I understand, is supposed to have the .errors and .errors.any functions.

And my controller:

class ArticlesController < ApplicationController

    def new
      @article = Article.new
    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

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

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

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

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

end

This leads me to two questions:

  1. Why is this error happening?
  2. What is the correct way to fix this?

Upvotes: 2

Views: 5190

Answers (3)

Gowtham Nagaraj
Gowtham Nagaraj

Reputation: 11

There is no active class in new method . Just add @article = Article.new in articles_controller.rb in new method.

Upvotes: 1

Mischa
Mischa

Reputation: 43318

You have to put the edit and update methods above private. Anything below private will be a private method and edit and update should be public methods.

Upvotes: 8

Logan Serman
Logan Serman

Reputation: 29880

This is such a common mistake people make and it drives me crazy. Read what the error message says:

undefined method `errors' for nil:NilClass

This has NOTHING to do with the Article model and what methods it does or does not have. It has to do with the LACK OF an Article model to act on. That is why errors being called on nil:NilClass instead of some instance of Article.

Your @article variable is not being set (or it is being set to exactly nil) in your controller, which you haven't posted.

Upvotes: 0

Related Questions