我刚刚开始“在Rails上构建你自己的Ruby”并且我不得不经常使用Google,因为这本书似乎有很多代码不起作用的地方。这一次,我找不到答案。好的,所以这是交易。我的表格看起来像这样:
new.html.erb
:
<%= form_for :story do |f| %>
<p>
name:<br />
<%= f.text_field :name %>
</p>
<p>
link: <br />
<%= f.text_field :link %>
</p>
<p>
<%= submit_tag %>
</p>
<% end %>
当我去localhost:3000/story/new
时显示正常。问题是,当我尝试在表单中键入内容并按“提交”时,我收到此错误:
Routing Error
No route matches [POST] "/story/new"
我的routes.rb
看起来像这样:
FirstApp::Application.routes.draw do
resources :story
story_controller
看起来像这样:
def new
@story = Story.new(params[:story])
if request.post?
@story.save
end
end
story_controller
的{{1}}内容完全出自本书。我以为我可能有一个解决方案here,但没有骰子。任何帮助将不胜感激。
答案 0 :(得分:2)
我猜你的意思(请注意at符号):
<%= form_for @story do |f| %>
这可能会解决您的路由问题,但正如John所提到的,您的控制器操作也有点过时了。 new
操作应仅加载虚拟模型并显示new.html.erb页面 - 保存应在单独的操作中进行,名为create
。
希望这有帮助!
编辑:最少的控制器代码:
class StoriesController < ApplicationController
def new
#Make a dummy story so any default fields are filled correctly...
@story = Story.new
end
def create
@story = Story.new(params[:story])
if(@story.save)
#Saved successfully; go to the index (or wherever)...
redirect_to :action => :index
else
#Validation failed; show the "new" form again...
render :action => :new
end
end
end
答案 1 :(得分:1)
首先,当使用单数和复数名称时,Rails依赖于约定优于配置。如果您想遵守惯例,则必须将routes.rb
中的行更改为resources :stories
,这会产生以下路线:
stories GET /stories(.:format) stories#index
POST /stories(.:format) stories#create
new_story GET /stories/new(.:format) stories#new
edit_story GET /stories/:id/edit(.:format) stories#edit
story GET /stories/:id(.:format) stories#show
PUT /stories/:id(.:format) stories#update
DELETE /stories/:id(.:format) stories#destroy
请注意,在这种情况下,您必须将控制器重命名为StoriesController
。但是,您的routes.rb
有resources :story
,会产生以下路线:
story_index GET /story(.:format) story#index
POST /story(.:format) story#create
new_story GET /story/new(.:format) story#new
edit_story GET /story/:id/edit(.:format) story#edit
story GET /story/:id(.:format) story#show
PUT /story/:id(.:format) story#update
DELETE /story/:id(.:format) story#destroy
正如您所看到的,确实没有POST /story/new
的路线。我想,你得到的错误是由控制器中的以下代码触发的:
if request.post?
@story.save
end
这是非常错误的,因为您尝试在POST
路由到的操作中检查GET
请求。只需从new
操作中删除此代码,然后将create
操作添加到StoryController
,就像这样:
def create
@story = params[:story]
if @story.save
redirect_to @story, notice: "Story created"
else
render action: "new"
end
end
这应该暂时解决您的问题。但我强烈建议您使用复数stories
作为资源,因为它会再次困扰您。
答案 2 :(得分:1)
这是你(和我)错过指南的部分:
但这种形式存在一个问题。如果您检查HTML 通过查看页面来源生成的,您将看到 表单的action属性指向/ articles / new。 这是一个问题,因为这条路线会转到你所在的页面 此时此刻,该路线应仅用于展示 新文章的形式。
表单需要使用其他网址才能转到其他地方。 这可以通过form_for的
通常在Rails中,用于新表单提交的操作 像这样称为&#34;创建&#34;,因此应该指出表单 那个动作。 编辑app / views / articles / new.html.erb中的form_for行,如下所示:
<%= form_for :story, url: stories_path do |f| %>