1

我刚刚开始“在 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东西new是直接出书。我想我可能在这里有一个解决方案,但没有骰子。任何帮助将不胜感激。

4

3 回答 3

2

我猜你的意思是(注意 at 符号):

<%= form_for @story do |f| %>

这可能会解决您的路由问题,但正如约翰所提到的,您的控制器操作也有点偏离。该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
于 2012-06-10T18:10:04.657 回答
1

这是您(和我)从指南中遗漏的部分:

但是,这种形式存在一个问题。如果您检查生成的 HTML,通过查看页面的源代码,您将看到表单的 action 属性指向 /articles/new。这是一个问题,因为此路由会转到您当前所在的页面,并且该路由仅应用于显示新文章的表单。

表单需要使用不同的 URL 才能转到其他地方。 这可以通过 form_for 的 :url 选项非常简单地完成。 通常在 Rails 中,用于提交此类新表单的操作称为“创建”,因此表单应指向该操作。

编辑 app/views/articles/new.html.erb 中的 form_for 行,如下所示:


<%= form_for :story, url: stories_path do |f| %>
于 2014-06-22T05:25:06.077 回答
1

首先,Rails 在使用单数和复数名称时依赖于约定而不是配置。如果要遵循约定,则必须更改 to 中的行routes.rbresources :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.rbhasresources :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作为您的资源,因为它会再次困扰您。

于 2012-06-10T18:22:09.180 回答