[英]NoMethodError in Rails app, method 'error' undefined
I am trying to create a Rails blog app with this tutorial 我正在尝试通过本教程创建一个Rails博客应用
I am stuck on the step that validates that the fields a user enters are not empty. 我停留在验证用户输入的字段不为空的步骤上。 However, if I try to pass empty fields, I get this error:
但是,如果我尝试传递空字段,则会出现此错误:
NoMethodError in Posts#create
Showing C:/Users/irowe/Documents/GitHub/Rails-Blog/blog/app/views/posts/new.html.erb where line #3 raised:
undefined method `errors' for nil:NilClass
Here is my post controller: 这是我的后控制器:
class PostsController < ApplicationController
def index
@posts = Post.all.order(created_at: :desc)
end
def show
end
def new
@post = Post.new
end
def create
p = Post.new(title: params[:post][:title], content: params[:post][:content])
if p.save
flash[:notice] = 'Successfully created a new post!'
redirect_to root_path
else
flash[:alert] = 'Something went awry...'
render :new
end
end
end
and my "new post" view 和我的“新帖子”视图
<h1>New Post</h1>
<ul>
<% @post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<%= form_for @post, url: create_post_path do |f| %>
<%= f.text_field :title %>
<br />
<%= f.text_area :content %>
<br />
<%= f.submit %>
<% end %>
And the post model 和后期模型
class Post < ActiveRecord::Base
validates_presence_of :title
validates_presence_of :content
before_validation :preval
private
def preval
if self.title
self.title = self.title.strip
end
if self.content
self.content = self.content.strip
end
end
end
I have seen other answers like this but they just recommend to make sure post
is not nil
, which I have made sure it isn't. 我见过其他答案喜欢这个 ,但他们只是建议,以确保
post
不nil
,这是我确定它是不是。 Any ideas on how to make sure the validation woks? 关于如何确保验证功能的任何想法? I am totally new to Rails.
我对Rails完全陌生。
You have to change your variable local into instances variable. 您必须将本地变量更改为实例变量。 To make instances variable, you can only add
@
. 要使实例可变,只能添加
@
。 It means the variable can be used in your new.html.erb file. 这意味着该变量可以在new.html.erb文件中使用。 For example:
例如:
def create
@post = Post.new(title: params[:post][:title], content: params[:post][:content])
if @post.save
flash[:notice] = 'Successfully created a new post!'
redirect_to root_path
else
flash[:alert] = 'Something went awry...'
render :new
end
end
This is good tutorial from rails guide rails guide to get started . 这是从rails guide rails入门的好教程。 I hope this tutorial can help you a lot.
希望本教程对您有所帮助。
NilClass 零类
The error you're getting is standard if Rails is trying to manipulate an object which doesn't exist... 如果Rails试图操纵一个不存在的对象,那么您得到的错误是标准错误。
for nil:NilClass
For Ruby, there is no such thing as Nil
- it translates it into a NilClass
object. 对于Ruby,没有
Nil
这样的东西-它会将其转换为NilClass
对象。 Thus, if you're trying to call the errors
method on this object, it will raise an exception. 因此,如果您尝试在此对象上调用
errors
方法,它将引发异常。
The error is with this line: 错误是与此行:
<% @post.errors.full_messages.each do |msg| %>
Now, this won't be the cause of the error, just the symptom. 现在,这将不是错误的原因 ,而只是症状。 It means that
@post
doesn't exist. 这意味着
@post
不存在。 To remedy this, you need to look at why: 为了解决这个问题,您需要查看原因:
def create
p = Post.new(title: params[:post][:title], content: params[:post][:content])
if p.save
flash[:notice] = 'Successfully created a new post!'
redirect_to root_path
else
flash[:alert] = 'Something went awry...'
render :new
end
end
With this, you need to do several things: 这样,您需要做几件事:
Instance Variable 实例变量
You need to make an instance variable , which will then be available in the view: 您需要创建一个实例变量 ,该变量随后将在视图中可用:
def create
@post = Post.new post_params
if @post.save
This should allow your view to access the @post
variable (which it wouldn't do it it were just local in scope). 这应该允许您的视图访问
@post
变量(它不会这样做,因为它只是作用域中的局部变量)。
Conditional 有条件的
Secondly, you may wish to make the errors
invocation conditional: 其次,您可能希望使
errors
调用成为条件:
<% if @post.errors.any? %>
<% @post.errors.full_messages.each do |msg| %>
This should get it working for you. 这应该使它为您工作。
The issue is in your create
action. 问题出在您的
create
操作中。 In it, you are using the local variable p
to store the Post
. 在其中,您正在使用局部变量
p
来存储Post
。 However, when the validations fail, your code renders the new
view. 但是,当验证失败时,您的代码将呈现
new
视图。 That view is looking for the instance variable @post
. 该视图正在寻找实例变量
@post
。 So simply, change your code to this: 简单地说,将您的代码更改为此:
@post = Post.new(title: params[:post][:title], content: params[:post][:content])
if @post.save
I'm guessing you don't get the error when you open the new
form, but only when you submit the form and it has errors. 我猜您在打开
new
表单时不会收到错误,而只是在提交表单时发现错误。
That would be because you render the new
form again here: 那是因为您在这里再次渲染
new
表单:
flash[:alert] = 'Something went awry...'
render :new
render
simply renders the form, it does not redirect to the new
action. render
仅呈现表单,它不会重定向到new
操作。
And you never set post
in your create
action. 而且,您永远不会在
create
动作中设置post
。
An easy fix would be to change these two lines 一个简单的解决方法是更改这两行
p = Post.new(title: params[:post][:title], content: params[:post][:content])
if p.save
to this: 对此:
@post = Post.new(title: params[:post][:title], content: params[:post][:content])
if @post.save
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.