如何使用rails 5对turbolinks 5进行回复

时间:2017-09-14 15:43:03

标签: ruby-on-rails-5 turbolinks-5

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

例如,采用标准的rails 5.1.4生成的app生成如下:

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)   - 控制器收到更新请求   - 修改对象(并保存)   - 返回重定向   - 呈现Rediredted网址   - DOM已更新 随着B)   - 控制器收到更新请求   - 修改对象(在内存中)   - 呈现响应   - 浏览器收到响应,但忽略

收到的回复看起来是正确的。完整的HTML,包含对对象的更改。如何让turbolinks注意到它并像普通文件一样替换document.body?

整个项目,包括development.log是on Github

1 个答案:

答案 0 :(得分:3)

问题在于,在Rails 5中:

  • 默认情况下,表单是远程的:除非提供local: true,否则它们都是通过AJAX发送的
  • 在将HTML呈现为对AJAX调用的响应时,除非在客户端中处理响应的自定义javascript,否则什么都不会发生
  • 默认情况下,Turbolinks是启用的,它可以正确处理redirect_to,但对render不起作用

我认为这是Rails中的不一致之处,会引起很多混乱,例如您在代码中遇到的问题。我创建了一个gem turbolinks_render来解决这个问题。我也是wrote a little post on this very same problem

我希望以某种方式在将来的Rails版本中解决此问题。