ruby-on-rails 如何在Rails应用程序中禁用Hotwire / Turbo(Turbolinks替代品)?

yvt65v4c  于 2023-03-24  发布在  Ruby
关注(0)|答案(4)|浏览(157)

在Rails 7中,Turbolinks被Hotwire / Turbo取代。这修补了Web链接,使它们成为AJAX风格的请求,就像Turbolinks一样,但也修补了表单。总的来说,我们发现这破坏了我们的应用程序。

  • 已经附加了某种JS行为的表单会发生冲突。
  • 标准Rails错误处理习惯用法-“设置flashrender :new/render :edit“- break,令人惊讶;必须加上status: :unprocessable_entity并交叉手指。
  • 如果处理表单提交的控制器重定向到包含补丁锚(...#foo)的URL,则Turbo会将其剥离。

最后,data: {turbo: false}只有这么多,分散在代码库中才有意义。更糟糕的是,我们使用的是SimpleForm,所以这就变成了更麻烦的html: {data: {turbo: false}}
是否有一种方法可以只对表单**(理想情况下,* 所有 * 表单,无论它们的来源是什么-请完全保留<form>标签和其中的所有内容)全局禁用Turbo**,但保持其其余行为不变?

e5njpo68

e5njpo681#

我在Stack Overflow上发布了这个Q&A,因为我找不到任何其他的解决方案。显然,有很多缺点,我更希望看到一个简单的配置标志,让它忽略表单-这将是一个压倒性的首选方法。
我仍然没有一个完整的解决方案,因为Rails内部生成的表单(例如link_to(...method: delete))仍然是一个问题,但我确实使用了一些猴子补丁来解决它。
一方面,有Rails表单:

  • 显然,data-turbo属性的值适用于该节点 * 和所有子节点 *,因此可以使用该属性集 Package 例如Rails生成的“动态”表单,例如DIV中的link_to(...method: delete),并且至少在逐案基础上解决这些问题- * 尽管注意,我在某些情况下仍然难以实现这一点 *。
  • 如果你有很多这样的,虽然,这将是侵入性和丑陋的,所以它仍然是很好的有一种方法,让涡轮只是忽略形式完全。

另一方面,还有SimpleForm表单:

  • SimpleForm没有提供全局配置数据属性的方法,这些属性将被添加到它构造的form元素中。GitHub问题中以前的请求到目前为止被显式拒绝。
  • SimpleForm似乎没有提供任何方法来配置一个 Package 器,将 form 作为一个整体,只有自定义 Package 器的 * 输入 * 在一个表单中。所以我们不能很容易地只是例如写一个 Package 器DIV如上所述。

我碰巧参与了一个gem called Hoodooprovides monkey patching facilities可以让你编写更像子类的补丁模块-super可以调用补丁实现-而且,补丁可以动态轻松地启用或禁用。Hoodoo实际上是一个Rack应用程序服务框架,所以这是一个大锤的东西-我总是打算有一天提取到它自己的宝石,但在写作的时候,我还没有抽出时间来做这件事(几年过去了)--但是我们可以只做我们需要的部分,而忽略其余的部分。
在这里,我修补了SimpleForm的构建器方法。这些方法只是在后台调用Rails的表单帮助器,所以我可能会尝试在Rails中修补更低的部分,但无论如何,下面的方法是有效的。
Gemfile中,声明Hoodoo依赖项,但不要加载其所有组件部分,因为您不需要大部分组件。

# Hoodoo's monkey patch module is useful sometimes:
# https://rubygems.org/gems/hoodoo
#
# MUST use 'require: false' so that the Rack components of Hoodoo middleware
# do not get activated; this is a Rails app, not a Hoodoo service!
#
gem 'hoodoo', '~> 2.12', require: false

...然后写一个类似config/initializers/simple_form_monkey_patch.rb的东西,看起来像这样:

require 'hoodoo/monkey'

module SimpleFormMonkey
  module InstanceExtensions
    def simple_form_for(record, options = {}, &block)
      modified_options = {html: {data: {turbo: false}}}
      modified_options.deep_merge!(options)

      super(record, modified_options, &block)
    end
  end
end

Hoodoo::Monkey.register(
  extension_module: SimpleFormMonkey,
  target_unit:      SimpleForm::ActionViewExtensions::FormHelper
)

Hoodoo::Monkey.enable(
  extension_module: SimpleFormMonkey
)

...这就可以了。这有一些风险,因为我们正在修补的东西-在模块名称和嵌套方面-在技术上是SimpleForm私有的,但方法签名本身至少是公共的。你可以用form_for的覆盖来修补ActionView::Helpers::FormHelper,如果你想去低层次的修补一个已经稳定了很长一段时间的API,代码几乎是相同的,因为方法签名是相同的。

xytpbqjk

xytpbqjk2#

我用JavaScript来解决这个问题:

document.querySelectorAll('form').forEach(function (el) {
    el.dataset.turbo = false
  })

没有更多的片状系统测试,由于随机失踪的闪光消息/警报后,形式提交和设计也完美地再次工作。

stszievb

stszievb3#

@kamilpogo你的解决方案工作起来像一个魅力!ty!!!目前正在学习和遵循this GoRails tutorial之前,我遇到了一些涡轮麻烦,试图呈现“谢谢!”其他人在那里。
基本上,我将javascript添加到/layouts/application.html.erb中,如下所示:

<script>    
    document.querySelectorAll('form').forEach(function (el) {    
                el.dataset.turbo = false    
    })    
</script>    
<script src="js-bootstrap"></script>    
  </body>    
</html>

更新:视频中的评论有一个不同的工作环境,在表单中将turbo设置为“false”,将local设置为“true”:

form_with model: @user, url: sign_up_path, local: true, data: { turbo:false } do |form|
xggvc2p6

xggvc2p64#

您可以通过在application.js中添加以下行来禁用turbo drive

import { Turbo } from "@hotwired/turbo-rails"
Turbo.session.drive = false

更多信息:https://turbo.hotwired.dev/handbook/drive#disabling-turbo-drive-on-specific-links-or-forms

相关问题