Reputation: 33
I'm new to ruby and i'm learning, so i was following this tutorial http://guides.rubyonrails.org/getting_started.html but when i try to add the error message i get undefined method `errors' for nil:NilClass at this piece of code:
<h1>New Article</h1>
<%= form_for :posts, url: posts_path do |f| %>
<% if @post.errors.any? %> // <-- **HERE**
<div id="error_explanation">
<h2>
<%= pluralize(@post.errors.count, "error") %> prohibited
This is my controller:
class PostsController < ApplicationController
def index
@posts = Post.all
end
def new
@posts = Post.all
end
def create
@posts = Post.new(posts_params)
if @posts.save
redirect_to @posts
else
render 'new'
end
end
def show
@posts = Post.find(params[:id])
end
private
def posts_params
params.require(:posts).permit(:title, :description)
end
end
This is my view that is giving me an error in full:
<h1>New Article</h1>
<%= form_for :posts, url: posts_path do |f| %>
<% if @post.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(@post.errors.count, "error") %> prohibited
this post from being saved:
</h2>
<ul>
<% @post.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 :description %><br>
<%= f.text_area :description %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Back', posts_path %>
My model:
class Post < ActiveRecord::Base
validates :title,
:presence => {:message => "Title can't be blank." },
:uniqueness => {:message => "Title already exists."},
length: { minimum: 5 }
validates :description,
:presence =>{:message => "Description can't be blank." }
end
Can someone help me?
Upvotes: 2
Views: 829
Reputation: 76774
The error is that you've not declared @post
--
You need to do the following:
#app/controllers/posts_controller.rb
class PostsController < ApplicationController
def new
@post = Post.new
end
end
#app/views/posts/new.html.erb
<%= form_for @post do |f| %>
<% if @post.errors.any? %>
...
<% end %>
<%= f.submit %>
<% end %>
This will set the correct @post
variable, which should give you the ability to call the .errors
method on it.
As a sidenote,
undefined method `errors' for nil:NilClass
This error is often confused with new developers.
They think that their problem is errors
method is missing; the real issue is that your variable is undeclared
Since Ruby is object orientated, it treats each variable as an object. Unlike other languages - which would raise exception based on the variable being undeclared, Ruby populates the nil:NilClass
object.
Thus, whenever you see the above error, always remember that it means you've called a non-declared variable.
Upvotes: 0
Reputation: 148
I would like to suggest, just one thing :-
you can try like :-
In controller
def new
@post = Post.new
end
and In your View
<%= form_for :post, url: posts_path do |f| %>
<% if @post.errors.any? %>
---you code here --
<% end %>
<% end %>
new
action can be used to validate the params just before saving into the database hence calling some_obj = obj.new(params)
and then som_obj.errors
would definetly have the errors listed if valid params are not provided
Upvotes: 1
Reputation: 96767
You have the following:
<% if @post.errors.any? %>
but in your controller, you have:
def new
@posts = Post.new
end
def create
@posts = Post.new(posts_params)
...
end
Rename @posts
to @post
in your controller.
So, the code has to look like this:
def new
@post = Post.new
end
def create
@post = Post.new(posts_params)
...
end
Upvotes: 2