我有一个非常令人沮丧的问题。这是流程:
我有一个模型项目和一个模型测试。项目有很多测试。
在项目show
页面中,我按下一个按钮“添加测试”:
<%= link_to "Add test", new_project_test_path, :remote => true %>
这调用了new
我的方法tests_controller
:
def new
@project = Project.find(params[:project_id])
@test = Test.new
end
由于是远程调用,这将在new.js.erb
之后调用,它有:
$("#tests_table").append("<%= escape_javascript(render 'form', test: @test, project: @project) %>")
这将显示一个表单 _form.html.erb,其开头为:
<%= form_for([@project, test], :remote => true ) do |f| %>
填写完表格后,我点击了提交按钮(“创建测试”),它调用了以下create
方法:
def create
@project = Project.find(params[:project_id])
@test = @project.tests.create(test_params)
end
end
由于表单是远程的,这将create.js.erb
在完成后调用,它具有:
$("#tests_table").append("<%= escape_javascript(render 'test', test: @test, project: @project) %>");
这将添加以下内容_test.erb.html
:
<%= render "tests/form", test: test, project: @project %>
测试行始终处于可编辑状态,这就是 _test 部分继续显示表单的原因。
现在新行插入了正确的值,提交按钮显示“更新测试”。
但是,当我在这个新插入的表单上点击更新测试时,它没有通过并且 Javascript 控制台显示 POST 请求失败:
没有路线匹配 [POST] "/projects/5230920870dbf2ba260000e8/tests/5230ae3970dbf2ec30000239"
怎么会这样?具有该 ID 的新测试对象存在,这是 100% 的事实。我可以在 Rails 控制台中检索它。如果我刷新页面然后点击更新测试,它就会通过。但只有当我通过 Javascript 新插入行并点击更新测试时,它才通过。你看到这里有什么看起来阴暗的东西吗?
我的routes.rb
有:
resources :projects do
resources :tests
end
请记住,我可以向该 URL 发出 POST 请求,并且它可以在整个页面刷新时工作,但是当对象是新的并且使用 Javascript 动态插入表单时,会发生一些可疑的事情。
相关 rake 路由输出:
project_tests GET /projects/:project_id/tests(.:format) tests#index
POST /projects/:project_id/tests(.:format) tests#create
new_project_test GET /projects/:project_id/tests/new(.:format) tests#new
edit_project_test GET /projects/:project_id/tests/:id/edit(.:format) tests#edit
project_test GET /projects/:project_id/tests/:id(.:format) tests#show
PATCH /projects/:project_id/tests/:id(.:format) tests#update
PUT /projects/:project_id/tests/:id(.:format) tests#update
DELETE /projects/:project_id/tests/:id(.:format) tests#destroy
更新详情
在进一步检查 JS 控制台后,我发现了以下详细信息。
如果我在进入页面时已经存在的表单上点击“更新测试”,您会看到以下表单数据:
该调用返回 200 Success。
但是,如果我在使用上述步骤通过 JS 动态添加的表单上点击更新测试,它会显示:
那一个失败了,找不到 404。
为什么表单在第二种情况下不使用 _patch?这个答案说如果对象被持久化,表单应该使用 PUT,并且我已经在我的 rails 控制台中确认该对象实际上是持久化的。