如何在Rails 5中使用Turbolinks 5渲染回复

3

我有一个控制器的操作,在这里我希望接收表单数据,执行一些业务逻辑,然后刷新表单。如果我将对象保存在数据库中,然后使用redirect_to,它可以正常工作。但我更喜欢在内存中编辑对象并直接渲染响应。

例如,以rails 5.1.4生成的标准应用程序为例:

rails new turbolinks_example
rails g scaffold Thing name
rails db:migrate

表单已适当编辑以缩短长度并启用 turbolinks:

<%= form_with(model: thing) do |form| %>
  <div class="field">
    <%= form.label :name %>
    <%= form.text_field :name, id: :thing_name %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

A) 现在我们编辑控制器以更改对象。这使用重定向进行编辑,可以正常工作:

ThingsController < ApplicationController
...
  def update
    if @thing.update(thing_params)
      @thing.update name: "#{@thing.name} is OK"
      redirect_to edit_thing_path(@thing)
    end
  end 

B)这使用了一个渲染器,但不起作用:

class ThingsController < ApplicationController
  ...
  def update
      if @thing.update(thing_params)
        @thing.name = "#{@thing.name} is OK"
        render :edit
      end
  end
end

使用方案A: - 控制器接收更新请求 - 对象被修改(&保存) - 返回重定向 - 渲染重定向的url - 更新DOM

使用方案B: - 控制器接收更新请求 - 对象在内存中被修改 - 响应被渲染 - 响应被浏览器接收,但被忽略
接收到的响应看起来正确。它包含完整的HTML以及对对象所做的更改。我该如何让turbolinks注意到并像平常一样替换document.body呢?
完整的项目,包括development.log,可以在Github上找到:on Github

1个回答

3
问题在于,在Rails 5中:
  • 表单默认是远程的:除非提供local: true,否则它们将通过AJAX发送
  • 当将HTML作为响应发送到AJAX调用时,除非客户端中有自定义javascript处理响应,否则不会发生任何事情
  • Turbolinks默认启用,可以正确处理redirect_to,但对render无效
我认为这是Rails中的一种不一致性,导致了很多混淆,比如你在代码中暴露的问题。我创建了一个gem turbolinks_render来解决这个问题。我还写了一篇关于这个问题的小文章
我希望这个问题能以某种方式在未来的Rails版本中得到解决。

我安装了你的 gem,希望它能让我的表单提交。但是表单仍然无法提交。只有在给表单页面的 link_to 添加 data: { turbolinks: false } 时,表单才能正常工作。理想情况下,我希望保持 turbolinks 的开启状态。你的 gem 能解决这个问题吗?有很多关于表单由于 turbolinks 而无法提交的帖子(对我来说,唯一成功的处理方式是关闭 turbolinks)。 - stevec
你的代码可能有问题。你说的“表单无法提交”是什么意思?为了使远程表单工作(适用于Rails >= 5.1),你需要在application.js中添加//=require rails-ujs,或者对于早期版本使用jquery-ujs。也许你缺少了这个,因此远程表单无法正常工作。如果你能分享一些代码,我可以尝试帮助你。 - jmanrubia
我尝试将 //=require rails-ujs 添加到 application.js 中,但没有改变任何东西(表单仍然无法工作)。这里 有许多其他人遇到了类似的问题。我找到了一个解决方法,使用了carlosveucv提供的答案,但我认为这只是关闭了turbolinks而没有解决问题的根本原因。我同意Rails需要解决这个问题。但如果这不会发生,那么制作一个能够解决问题的gem可能是一个很好的临时解决方案。 - stevec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接