Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

RailsでのHotwireの使用

JavaScriptコードを記述せずに、ページの変更とフォームの送信を高速化し、複雑なページをコンポーネントに分割する方法を探している場合、この投稿はRailsをHotwireで次のレベルに引き上げるのに役立ちます。この記事では、サーバー側のレンダリングにツールを使用する方法を説明します。

Hotwireとは何ですか?

Hotwireは、JSONの代わりにHTMLをネットワーク経由で送信することにより、JavaScriptを記述せずに最新のWebアプリケーションを構築する方法を提供します。これにより、ページの読み込みが速くなります。 Railsは、従来のシングルページアプリケーション(SPA)に関連する速度や応答性を犠牲にすることなく、常にテクノロジーに組み込まれているため、サーバー側でのレンダリングを維持し、よりシンプルで生産性の高い開発エクスペリエンスを実現します。

Hotwireのコアはターボジェムです。これは、ページのナビゲーションとフォームの送信を高速化し、複雑なページをコンポーネントに分割し、WebSocket(ActionCable、チャネル、ストリーミングデータで構成される)を介してページの部分的な更新を送信する一連の補完的な手法です。

>

なぜそれを使用する必要があるのですか?

JavaScriptに苦労していて、ページ間をはるかに高速に移動する感覚でユーザーエクスペリエンスを向上させたい場合は、Hotwireが代わりになります。

Hotwireはどのように機能しますか? Hotwireは、サーバー側レンダリング(SSR)を使用して、SPAの主な利点を維持しながら、SPAに関連する問題のいくつかを解決します。 SSRはレンダリングプロセスを逆にし、従来の読み込みと同様に、SPAレンダリング作業の一部をサーバーにもたらします。 SSRは、レンダリングの一部がサーバー上で行われるため、ユーザーにアプリケーションのより効率的なロードを提供できます。パフォーマンスを向上させる可能性に加えて、インデックス作成などのSEOの問題に対処するのに役立ちます。

使い方は簡単ですか?

使い方はとても簡単です。 Railsプロジェクトのデフォルトパッケージ(Ruby、RoR、ActionCable、WebSocket)、すべてのJS依存関係をダウンロードするTurbo gem、およびWebSocketの閲覧中に一時データを保存するRedisが必要です。

TurboはTurboDrive、Frames、Streams、およびNativeによって補完されるため、単一ページのWebアプリケーションの速度を得るために別の言語(JS)を学ぶ必要はありません。ドライブはリンクとフォームを高速化し、ネットワークをリロードする必要性を減らします。一方、フレームはネットワークをよりロードしやすい独立したコンテキストに分割します。

Railsでどのように使用されますか?

このセクションでは、段階的な例を示します。

この例では、次のものが必要です。

  • ルビー
  • Ruby on Rails
  • Redis
  • SQLite(デフォルトのデータベース)
  • ジェムホットワイヤー
  • TurboRails
  • StimulusJS
  • WebSocket
  • ActionCable

どのプロジェクトを作成しますか?

ソーシャルメディアプロジェクトを作成します。

まず、ターミナルを開きます。新しいRailsプロジェクトから始めましょう:

rails new social-media

プロジェクトを入力してください:

cd social-media
ホットワイヤーの追加

Hotwireジェムをプロジェクトに追加します:

bundle add hotwire-rails

または、Gemfileを開きます そしてこれを追加します:

gem "hotwire-rails"

2番目のオプションを使用する場合は、今すぐバンドルを実行する必要があります。

bundle install

次に、インストールします。

rails hotwire:install
初期設定

今こそ、Hotwireが行った初期設定を分析する絶好の機会です。 Gemfileにアクセスすると、次のようになります。

gem 'redis', '~> 4.0'

なぜRedisが必要なのですか?

Redis gemが追加されたのは、ActionCableがWebSocketの閲覧中に一時データを保存するためにRedisgemを必要とするためです。ただし、Redisをインストールするだけでは使用できません。正しく構成されているかどうかを確認する必要があります。 config/cable.ymlに移動すると ファイルの場合、次のようになります。

development:
 adapter: redis
 redis://localhost:6379/1

アプリケーションを起動するときにRedisが実行されていることを確認してください(redis-server

JSの依存関係

package.jsonの依存関係を確認してください :

dependencies: {
 @hotwired/turbo-rails: ^7.0.0-beta.5,
 @rails/actioncable: ^6.0.0,
 @rails/activestorage: ^6.0.0,
 @rails/ujs: ^6.0.0,
 @rails/webpacker: 4.3.0,
 stimulus: ^2.0.0
}
モデルの生成

すべてのファイルをチェックした後、viewsを生成します 、controllersmodels およびmigrations postsの場合 bodyを含むテーブル 、およびlikes 列。これを行うには、ターミナルで次のコマンドを実行します。

rails g scaffold posts body:text likes:integer
データベースの作成

すべてが生成されたので、これらの変更をデータベースに送信する必要があるため、ターミナルで次のコマンドを実行します。

rails db:create db:migrate

すべてがうまくいけば、サーバーを実行できます(rails server )そしてすべてがOKかどうかを確認します。そのためには、サーバーを実行してから、postsにアクセスします。 ページ。https://localhost:3000/postsになります :

RailsでのHotwireの使用 投稿ディレクトリの印刷画面

投稿の一覧表示

次に、投稿を一覧表示します。そのために、app/views/posts/_post.html.erbを作成します ファイルを作成し、それに次のコードを追加します:

<div style="background: lightgrey; width: 300px; padding: 10px;">
  <%= post.body %>
  <br>
  <%= link_to :edit, edit_post_path(post) %>
  <%= button_to "likes (#{post.likes || 0})", post_path(post, like: true), method: :put %>
</div>
<br>
検証

本文フィールド(nullにすることはできません)を検証する必要があります。ブロードキャストに、作成後の最初のツイートと同じ画面にツイートを表示するように指示します。これを行うには、ファイルapp/models/post.rbを編集します 次のコードを挿入します:

class Post < ApplicationRecord
  validates_presence_of :body

  after_create_commit { broadcast_prepend_to :posts }
end
注文

投稿を注文する必要があるため、コントローラーを開きます(app/controllers/posts_controller.rb

...
def index
  @posts = Post.all.order(created_at: :desc)
  @post = Post.new
end
...
まとめ

それでは、indexを編集しましょう。 (app/views/posts/index.html.erbnew postを表示します ページとすべてのpostsのリスト 。

<%= turbo_stream_from :posts %>

<%= turbo_frame_tag :post_form do %>
  <%= render 'posts/form', post: @post %>
<% end %>

<%= turbo_frame_tag :posts do %>
  <%= render @posts %>
<% end %>
インデックスへのリダイレクト

最後に、createを変更しましょう コントローラのメソッド。 show postにリダイレクトされないようにするため ページ、すべてを同じページに保持しましょう。

...
def create
  @post = Post.new(post_params)

  respond_to do |format|
  if @post.save
   format.html { redirect_to posts_path }
   format.json { render :show, status: :created, location: @post }
 else
    format.turbo_stream { render turbo_stream: turbo_stream.replace(@post, partial: 'posts/form', locals: { post: @post }) }
    format.html { render :new, status: :unprocessable_entity }
   format.json { render json: @post.errors, status: :unprocessable_entity }
 end
  end
end
...

最終ページは次のようになります:

RailsでのHotwireの使用 最終ページの印刷画面

ログの確認

投稿が作成されたら、ターミナルログを確認してください。次のようになります:

[ActionCable] Broadcasting to posts: "<turbo-stream action=\"prepend\" target=\"posts\"><template><div style=\"background: lightgrey; width: 300px; padding: 10px;\">\n  first post\n  <br>\n  <a href=\"/posts/1/edit\">edit</a>\n  <form class=\"button_to\" method=\"post\" action=\"/posts/4?like=true\"><input type=\"hidden\" name=\"_method\" value=\"put\" /><input type=\"submit\" value=\"likes (0)\" /><input type=\"hidden\" name=\"authenticity_token\" value=\"<token>==\" /></form>\n</div>\n<br>\n</template></turbo-stream>"
考え

これは、次のように、ActionCableが超高速のパフォーマンスでターボストリームを処理していることを意味します。Completed 302 Found in 18ms

展開

Railsサーバーと一緒に実行するために別の実行可能ファイルが必要ですか?

いいえ、ActionCableはUnicorn、Puma、Passengerなどの一般的なサーバーで正常に動作するためです。

HerokuはHotwireをサポートしていますか?

はい、HerokuはHotwire(WebSocket)のベースをサポートしています。さらに質問がある場合は、Herokuの公式ドキュメントを確認してください。

なぜRedisを使用しているのか疑問に思われる場合は、もう1つ理由があります

HerokuをRedisなしで使用すると、アプリが複数のdynoにスケーリングされたときにメッセージがすべてのユーザーに送信されることはありません。現在のアプリはステートレスであるため、最初のdynoに接続されたクライアントは接続されたクライアントからメッセージを送信されません。 2番目のdynoに。 Redisは、メッセージの状態をグローバルストレージに保存することでこの問題を解決します。

HerokuでRedisを設定する

リモートRedisインスタンスとのRedisCLIセッションを確立するには、heroku redis:cliを使用します 。インスタンスを指定しない場合、REDIS_URLにあるインスタンス デフォルトで使用されます。複数のインスタンスがある場合は、接続するインスタンスを指定します。

アプリケーションサーバーではどのように機能しますか?

Redis pub-subシステムを使用するように各dynoを設定する必要があります。すべてのdynoは同じチャネル(デフォルト)にサブスクライブし、メッセージを待機します。各サーバーがメッセージを受信すると、接続されているクライアントにメッセージを公開できます。 subscribeについて説明します 別のスレッドで、subscribe はブロッキング機能であるため、メッセージを待機すると実行フローが停止します。さらに、接続でサブスクライブコマンドが実行されると、接続はサブスクライブを解除するかメッセージを受信することしかできないため、2番目のRedis接続が必要です。スケーリングの詳細については、こちらをご覧ください。

セキュリティ

現在、アプリケーションは公開されており、多くの攻撃に対して脆弱です。WSSを設定し、入力をサニタイズしてください。 WebSocketセキュリティの詳細についてはこちらをご覧ください。

結論

ここに示したように、新しいアプリケーションを介してHotwireを使用することは可能ですが、Turbolinksから更新することも可能です。

この記事は、「魔法のフレームワーク」がどのように機能するかを理解するのに役立つはずです。その中で、実際には、WebSocketを介した操作とナビゲーションを備えた集約されたターボストリームを介してリクエストを表示する小さなシンプルなアプリケーションを開発する可能性がありました。


  1. RailsでのTailwindCSSの使用

    CSSは魔法のようですが、時間がかかります。美しく、機能的で、アクセスしやすいサイトを使用するのは楽しいことですが、独自のCSSを作成するのは大変です。 Bootstrapなどの多くのCSSライブラリは近年爆発的に増加しており、Tailwindは2021年にパックをリードしています。 RailsにはTailwindが付属していませんが、この記事では、TailwindCSSを新しいRubyon Railsプロジェクトに追加する方法を説明します。これにより、設計の実装にかかる時間を節約できます。また、Tailwindのユーティリティクラスを使用した設計のウォークスルーも行います。このチュートリア

  2. Rails5でのAngularの使用

    あなたは前にその話を聞いたことがあります。分散型で完全に機能するバックエンドAPIと、通常のツールセットで作成されたフロントエンドで実行されているアプリケーションがすでにあります。 次に、Angularに移動します。または、AngularをRailsプロジェクトと統合する方法を探しているだけかもしれません。これは、この方法を好むためです。私たちはあなたを責めません。 このようなアプローチを使用すると、両方の世界を活用して、たとえばRailsとAngularのどちらの機能を使用してフォーマットするかを決定できます。 構築するもの 心配する必要はありません。このチュートリアルは、この目的のた