0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

はじめに

本記事は錆びかけたRailsの知識を頑張ってアップデートするアドベントカレンダー16日目です。

引き続きTurboを学習していて、ふと気になったことがありました。

それは、○○.turbo_stream.erbファイルの置き場です。

○○.turbo_stream.erbとは?

Turbo Streamを使って非同期通信を行う際、更新する要素の情報を書いておくファイルです。

例えば、コメント一覧とコメントの総数を非同期で更新したい場合を考えます。

以下のようなコメントを一覧表示しているviewがあるとします。

index.html.erb
<!-- app/views/comments/index.html.erb -->

<div id="comments_count">
  <%= pluralize(Comment.count, 'comment') %>
</div>

<div id="comments_list">
  <%= render @comments %>
</div>

このとき、以下のようにcreate.turbo_stream.erbというファイルを用意します。

app/views/comments/create.turbo_stream.erb
<%= turbo_stream.append "comments_list", partial: "comments/comment", locals: { comment: @comment } %>
<%= turbo_stream.update "comments_count", Comment.count %>

すると、comments_listおよびcomments_countの値を非同期で更新できるようになる、というものです。

○○.turbo_stream.erbファイルの置き場問題

これを見たとき、create.html.erbとファイルの置き場所がかぶるので別の場所に置いておけないかと思いました。同様の例にmailerのerbファイルがありますが、あれはどちらか消してしまうのであまり違和感を感じません。

ただその場合、通常のerbファイル(○○.html.erb)はそのままの場所に置いておきたいので、turbo_streamファイルの方だけを別に置く形になりそうです。

○○.turbo_stream.erbファイルの置き場候補

Turbo Streamsのファイルを別のフォルダにまとめて分けたい場合、Railsのビューパスの設定をカスタマイズすることになります。その場合、以下の方法が考えられます。

コントローラーレベルでのパスのカスタマイズ
カスタムレンダラーの作成

コントローラレベルでのビューパスのカスタマイズ

各コントローラで、レスポンスのフォーマットに応じてビューパスをカスタマイズすることができます。例えば、FugasControllerのhogeアクションでTurbo Streamのビューパスを設定するには:

controllerでの例
class FugasController < ApplicationController
  def hoge
    respond_to do |format|
      format.turbo_stream { render turbo_stream: "turbo_streams/hoge" }
      # 他のフォーマットに対するレスポンスもここに記述
    end
  end
end

この例では、app/views/turbo_streams/hoge.turbo_stream.erbに対応するビューファイルを使用するように指定しています。

カスタムレンダラーの作成

カスタムレンダラーを作成することで、特定のフォーマット(例えばTurbo Streams)に対して表示するビューを決めるロジックを変更できます。

custom_turbo_stream_renderer.rb
# lib/custom_turbo_stream_renderer.rb
module CustomTurboStreamRenderer
  def render(options = nil, extra_options = {}, &block)
    if options.is_a?(Hash) && options[:turbo_stream].present?
      options[:template] = "turbo_streams/#{options[:turbo_stream]}"
    end
    super(options, extra_options, &block)
  end
end

### コントローラーでこのモジュールをインクルード
```ruby:コントローラーでの例
class FugasController < ApplicationController
  include CustomTurboStreamRenderer
  # ...
end

この例では、turbo_streamオプションが指定された場合に、turbo_streamsディレクトリをビューパスとして使用するようにカスタマイズしています。

終わりに

調べてみて感じたのは、これらの手段はあまり使わない方が良い、ということです。
例えば複数のリソースが同じアクションでturbo_streamを利用する場合ファイル名が衝突しますし、Railsの規約から逸脱すると、将来的なメンテナンスやRailsのバージョンアップグレード時に問題が生じる危険もあるためです。

1つ目のやり方であればまだ検討の余地がありそうですが、よほど大量のstreamを使って混乱が生じそうな設計以外では使うメリットよりデメリットの方が大きくなってしまいそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?