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

使用Pagy gem时触发undefined method `model_name' for #Array报错如何解决

Rails Pagy分页报错undefined method `model_name' for Array 排查

报错根因

  • 你的查询语句末尾调用了Ruby原生方法sort_by(&:id),该方法会将ActiveRecord::Relation查询对象直接转换为普通数组,丢失了ActiveRecord模型的元数据方法(比如model_name)
  • 自定义的pagy_get_vars方法调用了collection.model_name获取模型i18n键,普通数组不具备该方法,直接触发报错
  • 额外隐患:数组的count方法不支持传参,你写的collection.count(:all)后续也会触发新的报错

解决方案

方案1:改为数据库层排序(推荐)

将sort_by(&:id)替换为ActiveRecord提供的order方法,全程保持Relation对象状态,无需转换数组,性能更高也符合Pagy的设计预期:

# data_controller.rb index方法修改后代码
def index
    @pagy, @datas = pagy(Data.active_only.where(data_location: @location).order(:id))
end

修改后无需调整其他代码即可解决问题。

方案2:适配Ruby层排序场景(仅用于SQL无法实现的复杂排序逻辑)

如果必须在Ruby层完成排序,可以通过以下两种方式适配:

方式A:修改pagy_get_vars方法兼容数组场景

# application_controller.rb修改后代码
def pagy_get_vars(collection, vars)
  # 兼容Relation和数组两种入参类型
  count = collection.is_a?(ActiveRecord::Relation) ? collection.count(:all) : collection.count
  item_path = if collection.is_a?(ActiveRecord::Relation)
                "activerecord.models.#{collection.model_name.i18n_key}"
              else
                # 数组场景指定对应模型的i18n键即可
                "activerecord.models.data"
              end
  { 
    count: count,
    page: params[vars[:page_param]||Pagy::VARS[:page_param]],
    item_path: item_path 
  }.merge!(vars)
end

方式B:分页时手动传入缺失参数

# data_controller.rb index方法修改后代码
def index
  relation = Data.active_only.where(data_location: @location)
  sorted_datas = relation.sort_by(&:id)
  # 手动传入count和item_path,覆盖pagy_get_vars的自动读取逻辑
  @pagy, @datas = pagy(sorted_datas, count: relation.count, item_path: "activerecord.models.data")
end

注意:Ruby层排序会将全量数据加载到内存再分页,数据量大时性能损耗极高,非必要不建议使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:24:05