1

I am following http://guides.rubyonrails.org/getting_started.html and trying to add validation to text field. My class:

class Article < ActiveRecord::Base

    validates :title, presence: true, length: { minimum: 5 }

    def new
      @article = Article.new
    end

    def create
    @article = Article.new(article_params)

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

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

end

My new.html.erb file:

<%= form_for :article, url: articles_path 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 %>

And when I try to add new article I open http://localhost:3000/articles/new but instead of the form I see error undefined method errors' for nil:NilClass because of the error in this line <% if @article.errors.any? %>

What am I missing here. Looks like @article is being validated before created? How can I fix it?

olyv
  • 3,699
  • 5
  • 37
  • 67
  • 1
    Instead of `form_for :article, url: articles_path` you can do `form_for @article` – Sergio Tulentsev May 13 '15 at 14:05
  • @SergioTulentsev The code is as-written in the Rails Guides, it's just copy-pasted. – user229044 May 13 '15 at 14:11
  • 2
    It looks like that you have copy pasted the code in wrong place, I dont think there is an issue with guide. even right before this code it says "Open the `app/models/article.rb` file and edit it:" – Abhinay May 13 '15 at 14:12

3 Answers3

7

Your model and controller are all meshed together into one class. That cannot work.

You need two classes:

  • A model called Article which inherits from ActiveRecord::Base
  • A controller called ArticlesController which inherits from ApplicationController

The code you've posted is the model, but the actions you've added (new and create) need to go in the controller.

The guide you're following says (note the file names):

Rails includes methods to help you validate the data that you send to models. Open the app/models/article.rb file and edit it:

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

And the below that,

... to do this, change the new and create actions inside app/controllers/articles_controller.rb to these:

def new
  @article = Article.new
end

def create
  @article = Article.new(article_params)

  # ...
user229044
  • 232,980
  • 40
  • 330
  • 338
  • 1
    Beat me to it - I was staring at the model in disbelief and since I'm so new at rails I wanted to check my own code before answering the same lol – sjagr May 13 '15 at 14:06
  • 2
    What a silly mistake! I used model class instead of controller. Oh my gosh. Of course, I moved code to the right place and now it's just fine. – olyv May 13 '15 at 14:12
0

validate part should reside in Modal which is Article < ActiveRecord::Base. and rest of your code should be Article controller

Abhinay
  • 1,796
  • 4
  • 28
  • 52
0

You have to put your validation in your model as :

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

And your actions should be in controller as :

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

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


end

And at last change you form as:

<%= form_for @article do |f| %>
Gaurav Gupta
  • 1,181
  • 10
  • 15