もふもふ技術部

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にできそうですね!!