0

Rails 7 では、Turbolinks は Hotwire / Turbo に置き換えられました。これは Web リンクにパッチを当てて、Turbolinks と同じように AJAX スタイルのリクエストにするだけでなく、フォームにもパッチを当てます。全体として、これがアプリケーションの一部を壊すことがわかりました。

  • ある種の JS ビヘイビアーが既に関連付けられているフォームが競合していました。
  • 標準的な Rails のエラー処理イディオム - "set the flashand render :new/ render :edit" - 驚くほど壊れます。指を追加status: :unprocessable_entityして交差させる必要があります。
  • フォーム送信を処理するコントローラーがパッチ アンカー ( ) を含む URL にリダイレクトする場合...#foo、Turbo はそれを取り除きます。

data: {turbo: false}最終的には、コード ベース全体に分散させることが理にかなっているほどの量しかありません。さらに悪いことに、SimpleForm を使用しているため、これはさらに扱いにくくなりhtml: {data: {turbo: false}}ます。

フォームに対してのみTurbo を _globally 無効にする方法はありますか(理想的には、フォームの起源に関係なくすべての<form>フォーム -タグとその中のすべてを完全にそのままにしてください)、残りの動作は変更しませんか?

4

1 に答える 1

0

他に解決策が見つからなかったため、この Q&A を Stack Overflow に投稿しました。明らかに、多くの欠点があり、Turbo にフォームを無視させる単純な構成フラグを表示することを強く望んでいます。これは圧倒的に好ましい方法です。

いずれにせよ完全な解決策はまだありません。たとえば、Rails によって内部的に生成されたフォームにlink_to(...method: delete)はまだ問題があるためです。ただし、いくつかのモンキー パッチを使用して回避しました。

一方では、Rails フォームがあります。

  • どうやら、data-turbo属性の値はそのノードとすべての子に適用されるため、Rails で生成された「動的な」フォームlink_to(...method: delete)などをその属性セットを持つ DIV でラップし、少なくとも、ケースバイケースでこれらの問題を回避できます。ケースベース -ただし、場合によってはまだこの作業に問題があります
  • ただし、これらがたくさんある場合、それは邪魔になり、醜いものになるため、Turbo がフォームを完全に無視するようにする方法があればなお良いでしょう。

一方、SimpleForm フォームがあります。

  • formSimpleForm は、構築する要素に追加されるデータ属性をグローバルに構成する方法を提供しません。GitHubの問題でのこれに対する以前のリクエストは、これまでのところ明示的に拒否されています.
  • SimpleForm は、フォーム全体を取り囲むラッパーを構成する方法を提供していないように見えます。フォーム内の入力用のカスタム ラッパーのみを提供します。そのため、上記のようにラッパー DIV を作成するなど、簡単にはできません。

私はたまたま、サブクラスに似たパッチモジュールを作成できるモンキーパッチ機能を提供するHoodooと呼ばれるgemに参加しました-パッチが適用された実装を呼び出すことができます-さらに、パッチは動的かつ簡単に有効または無効にできます. Hoodoo は実際には Rack アプリケーション サービス フレームワークであるため、これは大槌のようなものです。私は常にこれを独自の gem に抽出するつもりでしたが、執筆時点では実現できていません (そして数年が経過しました)。 by) - しかし、必要な部分だけを残して残りを無視することができます。superrequire

ここでは、SimpleForm のビルダー メソッドにパッチを適用します。これらは内部で Rails のフォーム ヘルパーを呼び出すだけなので、代わりに Rails の下位にパッチを適用することも考えられますが、次の方法でうまくいきました。

で、Hoodoo の依存関係を宣言しますGemfileが、ほとんどのコンポーネントを必要としないため、すべてのコンポーネント パーツをロードしないでください。

# 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 にプライベートですが、メソッド シグネチャ自体は少なくともパブリックです。より低いレベルに行き、非常に長い間安定している API にパッチを適用したい場合は、代わりにActionView::Helpers::FormHelperオーバーライドでパッチを適用できます。form_forメソッドのシグネチャが同じであるため、コードはほとんど同じです。

于 2022-01-31T04:33:09.273 に答える