You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Turbo Frame中使用Pagy实现过滤表格分页的异常问题

解决Rails+Turbo+Pagy过滤后分页丢失参数的问题

核心问题

过滤后的分页链接未携带搜索参数,点击分页时会请求默认的index动作,导致使用Record.all而非过滤后的查询条件;同时原代码将分页导航放在Turbo Frame外部,分页请求无法复用过滤参数。

解决方案步骤

1. 重构控制器:统一查询逻辑并生成带参数的Pagy实例

抽离过滤逻辑,让index和search动作复用,同时确保Pagy生成的分页链接携带过滤参数:

class RecordsController < ApplicationController
  def index
    filtered_records = filter_records
    @pagy, @records = pagy(filtered_records, items: 25, url: pagy_base_url)
  end

  def search
    filtered_records = filter_records
    @pagy, @records = pagy(filtered_records, items: 25, url: pagy_base_url)
    render partial: 'records_section', locals: { records: @records, pagy: @pagy }
  end

  private

  def filter_records
    records = Record.all
    records = records.where('name LIKE ?', "%#{params[:name]}%") if params[:name].present?
    records = records.where('type LIKE ?', "%#{params[:type]}%") if params[:type].present?
    records
  end

  def pagy_base_url
    # 生成携带当前过滤参数的基础URL,排除page参数避免冲突
    request.path_with_query_parameters.except(:page)
  end
end

2. 调整搜索表单:改用GET请求

POST请求的参数无法自动带入分页链接,改用GET更适配搜索过滤场景:

<div style="margin:0.75rem">
    <%= form_with url: records_path, method: :get,
        data: { turbo_frame:"records_section" } do |form| %>

        <%= form.text_field :name, value: params[:name] %>
        <%= form.text_field :type, value: params[:type] %>

        <%= form.button "Search", class:"btn btn-primary" %>
    <% end %>
</div>

3. 重构视图:将表格与分页导航放入同一Turbo Frame

确保分页请求在Turbo Frame内处理,且携带过滤参数:

新建_records_section.html.erb partial:

<%= turbo_frame_tag "records_section" do %>
    <table>
        <thead>
        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Type</th>
        </tr>
        </thead>
        <tbody>
        <% if records.present? %>
            <% records.each do |record| %>
                <tr>
                    <td><%= record.id %></td>
                    <td><%= record.name %></td>
                    <td><%= record.type %></td>
                </tr>
            <% end %>
        <% end %>
        </tbody>
    </table>

    <% if pagy.present? && pagy.pages > 1 %>
        <div class="pag-bar mt-5 pt-5">
            <%== pagy_bootstrap_nav(pagy) %>
        </div>
    <% end %>
<% end %>

修改index.html.erb:

<h1>Records</h1>

<%= render "record_search_form" %>
<%= render "records_section", records: @records, pagy: @pagy %>

4. 路由调整(可选)

若保留search动作,确保路由使用GET:

# config/routes.rb
resources :records do
  collection do
    get :search
  end
end

关键说明

  • GET请求:搜索过滤用GET,参数会显式出现在URL中,Pagy可自动携带这些参数生成正确的分页链接。
  • Turbo Frame包裹分页:将表格和分页导航放在同一Frame内,分页点击时在Frame内发起请求,不会跳转到全页。
  • Pagy的url参数:通过url: pagy_base_url指定基础URL,确保分页链接始终包含当前过滤条件,避免参数丢失。

内容的提问来源于stack exchange,提问作者Richard Wright

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 11:57:09