Routing Error: No route matches [POST] "/flex_quiz/new"

Routing Error: No route matches [POST] "/flex_quiz/new"

在我的 rails 应用程序中,我尝试使用部分表单在 newedit 视图上显示相同的测验。我可以看到新的视图页面,但是当我点击 <%= f.submit "Submit Answers" %> 时,我收到一条错误消息 No route matches [POST] "/flex_quiz/new".

这是我部分中的 form for 行:

<%= form_for @flex_quiz, url: url do |f| %>

以下是当地人在我的 new 观点中的看法:

 <%= render partial: "quiz", locals: { url: new_flex_quiz_path, method: :post } %>

还有我的 edit 观点:

<%= render "quiz", url: edit_flex_quiz_path(@flex_quiz), method: :put  %>

这是路线路径:

         Prefix Verb   URI Pattern                    Controller#Action
            ...     
flex_quiz_index GET    /flex_quiz(.:format)           flex_quiz#index
                POST   /flex_quiz(.:format)           flex_quiz#create
  new_flex_quiz GET    /flex_quiz/new(.:format)       flex_quiz#new
 edit_flex_quiz GET    /flex_quiz/:id/edit(.:format)  flex_quiz#edit
      flex_quiz GET    /flex_quiz/:id(.:format)       flex_quiz#show
                PATCH  /flex_quiz/:id(.:format)       flex_quiz#update
                PUT    /flex_quiz/:id(.:format)       flex_quiz#update
                DELETE /flex_quiz/:id(.:format)       flex_quiz#destroy

谁能建议如何解决这个问题?我看过几篇类似的帖子(比如 this and this),但由于我使用的是部分,所以这里的解决方案必须有所不同。

编辑

这是我在 flex_quiz_controller:

中的定义
class FlexQuizController < ApplicationController
before_action :require_sign_in

def show
  @flex_quiz = FlexQuiz.find(params[:id])
end

def new
  @flex_quiz = current_user.build_flex_quiz
end

def create
  @flex_quiz = FlexQuiz.new

  @flex_quiz.flex01 = params[:flex_quiz][:flex01]
  @flex_quiz.flex02 = params[:flex_quiz][:flex02]
  @flex_quiz.flex03 = params[:flex_quiz][:flex03]
  @flex_quiz.flex04 = params[:flex_quiz][:flex04]
  @flex_quiz.flex05 = params[:flex_quiz][:flex05]
  @flex_quiz.flex06 = params[:flex_quiz][:flex06]
  @flex_quiz.flex07 = params[:flex_quiz][:flex07]
  @flex_quiz.flex08 = params[:flex_quiz][:flex08]
  @flex_quiz.flex09 = params[:flex_quiz][:flex09]
  @flex_quiz.flex10 = params[:flex_quiz][:flex10]

  @flex_quiz.user = current_user

  if @flex_quiz.save
    flash[:notice] = "Quiz results saved successfully."
    redirect_to user_path(current_user)
  else
    flash[:alert] = "Sorry, your quiz results failed to save."
    redirect_to welcome_index_path
  end
end

def edit
  @flex_quiz = FlexQuiz.find(params[:id])
end

def update
  @flex_quiz = FlexQuiz.find(params[:id])

  @flex_quiz.assign_attributes(flex_quiz_params)

  if @flex_quiz.save
    flash[:notice] = "Post was updated successfully."
    redirect_to user_path(current_user)
  else
    flash.now[:alert] = "There was an error saving the post. Please try again."
    redirect_to welcome_index_path
  end
end

private
def flex_quiz_params
  params.require(:flex_quiz).permit(:flex01, :flex02, :flex03, :flex04, :flex05, :flex06, :flex07, :flex08, :flex09, :flex10)
end

end

如果您想要创建 新的flex_quiz 对象,那么您将想要POSTflex_quiz_index_path

请注意,在您的路由路径中,如果您查看 new_flex_quiz,HTTP 动词是 GET

可能有点不直观,但 new 操作实际上是一个 GET 请求。

应该在其中创建对象的操作是 create 操作。

所以要解决您的问题,这应该可以解决问题:

<%= render partial: "quiz", locals: { url: flex_quiz_index_path, method: :post } %>

编辑

  1. 您可以简单地在 form_for 中定义您的表单,而不是定义局部变量:

您还必须在控制器操作中定义 @flex_quiz(在您的情况下 neweditform_for 将自动推断出适当的 URL.

来自 documentation

However, further simplification is possible if the record passed to form_for is a resource, i.e. it corresponds to a set of RESTful routes, e.g. defined using the resources method in config/routes.rb. In this case Rails will simply infer the appropriate URL from the record itself.

  1. 您还需要将命名从单数形式更改为复数形式。

做可重用表格的rails是:

app/views/flex_quiz/_form.html.erb:

<%= form_for(@flex_quiz) do |f| %>
  # ...
<% end %>

app/views/flex_quiz/new.erb:

<h1>Create a new quiz</h1>
<%= render 'form' %>

app/views/flex_quiz/edit.erb:

<h1>Edit a quiz</h1>
<%= render 'form' %>

虽然使用当地人通常是个好主意,但这里不需要。请注意,我们只是将资源而不是 URL 传递给 form_for - 这是 约定优于配置 的作用,这也是 Rails 很棒的原因。

Rails 自行计算 URL 将什么用于 action 属性以及根据资源是否已保存使用什么方法。

然而,要使它起作用,您必须真正遵守约定。确保您使用的是正确的复数形式 (the plural of quiz is quizzes):

resources :flex_quizzes

class FlexQuizzesController < ApplicationController
end

不幸的是,当涉及到其余设置时,您需要重新设计。认为你可以用一个单一的模型来做到这一点是不太现实的。您通常会有多个具有关系的模型:

class Quiz
  has_many :questions
end

class Question
  belongs_to :quiz
  has_many :answers
end

class Answer
  belongs_to :question
end

class UserQuiz
  belongs_to :user
  belongs_to :quiz
end

class UserAnswer
  belongs_to :question
  belongs_to :answer
end

您可以使用一个或多个控制器让管理员创建测验,并使用一个单独的控制器让用户回答测验。这是一个非常常见的域,因此您应该能够找到大量示例。