我创建了一个非常简单的Rails 3.1应用程序,其基本内容如下:
我的 PostsController.rb 有new
,index
,create
方法:
def index
@posts = Post.all
render :index
end
def new
@post = Post.new
render :new
end
def create
@post = Post.new(params[:post])
if @post.save
render :index
else
render :new
end
end
new.html.erb 表单:
<%= form_for @post do |f| %>
<%= f.error_messages%>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.label :address %><br />
<%= f.text_field :address, :size=>60 %>
</p>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>
索引视图( index.html.erb ):
<table>
<% @posts.each do |post| %>
<tr>
...
</tr>
<% end %>
</table>
我的 routes.rb 已定义:
resources :posts
root :to => 'post#new'
综上所述,当提交新表单时,将调用 PostController 中的create
方法,然后在create
方法内,如果新帖子已保存成功地,它将render :index
,即呈现 index.html.erb 视图,此时情况正常。但我现在在 index.html.erb 视图中收到错误:
它抱怨<% @posts.each do |post| %>
中的 @posts 是 nil ,为什么???
-------------我也试过-------------------------
我尝试在redirect_to posts_path
方法中使用create
,然后我得到未定义的方法`posts_path_url'错误
我还尝试在redirect_to :index
方法中使用create
,然后我得到未定义的方法`index_url'错误
答案 0 :(得分:2)
发生错误是因为@posts
方法中没有Post#create
方法设置Post#index
变量,因为它位于redirect_to
中。您必须记住,渲染视图不会调用适当的控制器方法。
您想使用render
代替def create
@post = Post.new(params[:post])
if @post.save
redirect_to :posts
else
render :new
end
end
:
{{1}}
答案 1 :(得分:0)
这是因为对render的调用不会调用控制器上的索引方法,它只会解析视图的路径并呈现它。
如果您希望@posts出现,您必须自己在创建操作中设置它。
这适用于默认的new和create方法(生成脚手架),因为在这两个操作中,您都设置了相同的实例变量@post。只有在创建操作中,如果验证失败,您可以立即重用存储有不同错误的@post实例变量,并呈现新视图模板以显示错误的帖子表单。
如果您想重定向到帖子操作,您应该使用:
redirect_to posts_path