1

「Build Your Own Ruby on Rails」を始めたばかりで、この本にはコードが機能しない箇所がたくさんあるようで、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

私はあなたが意味したと推測しています(アットマークに注意してください):

<%= 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
于 2012-06-10T18:10:04.657 に答える
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.rbhas があります。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を追加するだけです:createStoryController

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 に答える
1

これは、あなた (および私) がガイドから見逃した部分です。

ただし、このフォームには 1 つの問題があります。ページのソースを表示して、生成された HTML を調べると、フォームのアクション属性が /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 に答える