もふもふ技術部

IT技術系mofmofメディア

【Rails7】JS不要!Hotwireで「もっと見る」を実装する

Rails6までは「もっと見る」などの動的な機能を実装する場合はJSが必須でした。
しかし、Rails7から標準搭載されたHotwire(Turbo)を使用すると、JSを使わずに「もっと見る」を実装することができます。
今回はHotwireを使った「もっと見る」の実装方法を紹介します。

下準備

  1. Gemをインストールする

    gem "kaminari"
    
  2. モデルを作る

    $ rails g model post
    

    20240813000000_posts.rb

    class CreatePosts < ActiveRecord::Migration[7.1]
     def change
       create_table :posts do |t|
         t.string :name
         t.timestamps
       end
     end
    end
    

実装する

  1. ルーティングを設定する
    config/routes.rb

    resources :posts, only: [:index]
    
  2. コントローラーの実装
    app/controllers/posts_controller.rb

    class PostsController < ApplicationController
      def index
        posts = Post.all
        if params[:page].present?
          @posts = posts.page(params[:page])
          render turbo_stream: turbo_stream.replace("posts", partial: "posts")
        else
          @posts = posts.page(1)
          render :index
        end
      end
    end
    
  3. viewsの実装
    app/views/posts/index.html.erb

    <%= render 'posts' %>
    

    app/views/posts/_posts.html.erb

    <% @posts.each do |post| %>
      <div><%= post.name %></div>
    <% end %>
    <%= turbo_frame_tag 'posts' do %>
      <% if @posts.next_page %>
        <%= link_to "もっと見る", posts_path(page: @posts.next_page), data: { turbo_stream: true } %>
      <% end %>
    <% end %>
    

    補足
    link_todata: { turbo_stream: true } のオプションをつけないと、リンクをホバーするだけで動作してしまいました。
    2024/08/13 現在のバージョンでは、このように動作するようです。

    github.com

終わり

なんと、これだけで実装完了です!!
コントローラーで params[:page] のクエリパラメータが存在するかどうかで描画する内容を変えています。
検索中などで同じSQLを発行したい場合などは posts = Post.all の部分を1箇所変えるだけで済みます。
別のアクションを追加して実装する場合は、 before_action などを使うとDRYにできそうですね!!