【问题标题】:Rails: Why do I get a 204 response from all but the first request?Rails:为什么除了第一个请求之外,我得到的都是 204 响应?
【发布时间】:2018-10-25 17:16:28
【问题描述】:

我的主页上有一个按钮。当点击它时,它会向forms_controller 发出 POST 请求,以便创建一个新表单。

我的按钮:

<%= link_to 'Add form', forms_path, id: 'add_form_button',
                                 class: 'btn btn-primary',
                                method: :post, remote: true %>

请求完成后,控制台会记录一条消息:

<script>
  $('#add_form_button').on('ajax:complete', function(){
    console.log('Request complete!');
    });
</script>

这是动作:

def create
  current_user.forms.create
end

我的路线是这样定义的:

Rails.application.routes.draw do
  devise_for :users
  root to: 'home#show'
  resources :forms, except: [:index]
  get 'user_forms' => 'partials#user_forms'
end

它按预期工作。每次单击按钮时,都会创建一个新表单并将消息记录到控制台。

但是,在创建表单之后,我想重新加载一个 div,以便我可以看到新创建的表单与其他表单一起列出:

$('#add_form_button').on('ajax:complete', function(){
  console.log('Request complete!')
  var user_forms = '#user_forms';
  $(user_forms).load('user_forms',function(){
    document.getElementById('add_form_button').scrollIntoView();
  });
});

.load('user_forms')... 的情况下,user_forms 是我为返回部分而创建的操作的路由:

class PartialsController < ApplicationController
  def user_forms
    render partial: 'home/user_forms'
  end
end

第一次单击该按钮时,它按预期工作:创建一个新表单,将消息记录到控制台,并使用部分重新加载 div,以便它列出新创建的表单。

但它不适用于后续点击。每次单击按钮时都会创建新表单,但不会重新加载 div,也不会将消息记录到控制台。我还在 Rails 终端中看到以下错误:

No template found for FormsController#create, rendering head :no_content
Completed 204 No Content in 454ms (ActiveRecord: 2.6ms)

我知道我没有在 forms_controller#create 中定义明确的响应,但我不明白为什么它第一次有效,而以后无效。是什么阻止了它第二次工作?

【问题讨论】:

  • 嗨,我假设你使用 Rails 5?如果没有提供模板,它默认返回 204。请参阅blog.bigbinary.com/2016/07/03/… 了解更多信息。这本身不是错误。除此之外,我认为您提供的内容没有任何其他问题。您能发布routes.rb 中的内容吗?还有没有其他js代码与DOM交互或者监听ajax事件?
  • 这是页面上唯一的JS。我将编辑我的问题以添加路线。

标签: ruby-on-rails ujs


【解决方案1】:

好的,我做了一个简单的例子(使用你提供的),它对我来说很好用。请注意,每次点击您应该只会看到 2 个请求。您是否看到其他警告、错误?

我做了一个简单的user_form partial 来证明表单是 ajax 加载的。

<table>
  <% Form.all.each do |f| %>
    <tr>
      <td><%= f.id %></td>
      <td><%= f.name %></td>
    </tr>
  <% end %>
</table>

所以,你的代码很好:)。我建议您查看其他罪魁祸首,例如 turbolink(它会弄乱您的 ajax)、自定义 js 脚本等。

【讨论】:

  • 啊。对于第一次单击,我看到两个请求:一个 POST 和随后的 GET 部分请求。以下点击只会导致 POST 请求。那个 204 是一个红鲱鱼。它遵循每个 POST 请求。
【解决方案2】:

错误告诉您FormsContoller#create 没有模板。因为您没有在该操作中明确添加render,Rails 正在尝试在forms/create.html.erb 下查找模板。

但您当然不想为创建操作呈现模板,因为它只响应 AJAX 帖子。

尝试在FormsContoller#create 操作的末尾添加显式渲染。类似render {}, status: :ok

不确定这是否可以解决您的表单呈现问题,但至少应该可以解决 No template found 错误。

【讨论】:

  • 通常你的内容中甚至不需要{},所以它可以是render nothing: true, status: :ok,或者一个很好的简写形式就是head :ok
【解决方案3】:

首先,我的问题的前提是完全错误的。每次点击后我都会收到 204,但第一次点击后会收到 200 状态的 GET 请求。我假设 200 是第一个 POST。 Kasperite 的建议是,每次点击我应该看到两个请求,这帮助我意识到了这一点。

我没有在我的问题中解释按钮本身位于用于填充重新加载的 div 的 user_forms 部分中。 (如果我提到它,我可能会立即看到问题。此外,我给部分本身起的名字应该是一个足够大的线索,它不应该在那里。)

$('#add_form_button').on('ajax:complete', function(){...} 第一次工作时,原来的按钮会从 DOM 中移除并替换为相同的按钮。

但是,由于这是一个完全不同的元素,因此事件侦听器不会附加到这个新按钮。

我已经解决了这个问题,只需将按钮放在部分之外。

【讨论】:

    猜你喜欢
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多