Routing Error: No route matches [POST] "/flex_quiz/new"
Routing Error: No route matches [POST] "/flex_quiz/new"
在我的 rails 应用程序中,我尝试使用部分表单在 new
和 edit
视图上显示相同的测验。我可以看到新的视图页面,但是当我点击 <%= 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
对象,那么您将想要POST
到flex_quiz_index_path
。
请注意,在您的路由路径中,如果您查看 new_flex_quiz
,HTTP 动词是 GET
。
可能有点不直观,但 new
操作实际上是一个 GET
请求。
应该在其中创建对象的操作是 create
操作。
所以要解决您的问题,这应该可以解决问题:
<%= render partial: "quiz", locals: { url: flex_quiz_index_path, method: :post } %>
编辑:
您可以简单地在 form_for
中定义您的表单,而不是定义局部变量:
您还必须在控制器操作中定义 @flex_quiz
(在您的情况下 new
和 edit
)form_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.
- 您还需要将命名从单数形式更改为复数形式。
做可重用表格的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
您可以使用一个或多个控制器让管理员创建测验,并使用一个单独的控制器让用户回答测验。这是一个非常常见的域,因此您应该能够找到大量示例。
在我的 rails 应用程序中,我尝试使用部分表单在 new
和 edit
视图上显示相同的测验。我可以看到新的视图页面,但是当我点击 <%= 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
对象,那么您将想要POST
到flex_quiz_index_path
。
请注意,在您的路由路径中,如果您查看 new_flex_quiz
,HTTP 动词是 GET
。
可能有点不直观,但 new
操作实际上是一个 GET
请求。
应该在其中创建对象的操作是 create
操作。
所以要解决您的问题,这应该可以解决问题:
<%= render partial: "quiz", locals: { url: flex_quiz_index_path, method: :post } %>
编辑:
您可以简单地在
form_for
中定义您的表单,而不是定义局部变量:
您还必须在控制器操作中定义 @flex_quiz
(在您的情况下 new
和 edit
)form_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.
- 您还需要将命名从单数形式更改为复数形式。
做可重用表格的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
您可以使用一个或多个控制器让管理员创建测验,并使用一个单独的控制器让用户回答测验。这是一个非常常见的域,因此您应该能够找到大量示例。