Rails安装Kaminari后paginate报total_pages未定义错误如何解决
问题报错
运行Rails测试时抛出如下错误:
ActionView::Template::Error: undefined method `total_pages' for nil:NilClass options[:total_pages] ||= scope.total_pages
- 报错触发点:视图文件中
<%= paginate @carts %>代码行 - 环境确认:Kaminari相关gem已正确引入,版本信息如下:
Using kaminari-core 1.2.2 Using kaminari-actionview 1.2.2 Using kaminari-activerecord 1.2.2 Using kaminari 1.2.2
- 排查结果:日志执行
puts @carts.size输出为0,确认@carts实例存在,但非用户场景下Kaminari分页作用域未激活;其他场景下使用@users = User.page params[:page]实现分页时,测试运行无异常。
根因分析
对应控制器业务逻辑如下,非用户场景下@carts被直接赋值为原生空数组:
if user? @carts = Cart.order(created_at: :desc).where([user_id = ?, current_user.id]).page params[:page] else @carts = [] end
Kaminari的paginate视图辅助方法要求传入参数必须是携带分页元数据(包含total_pages、current_page等实例方法)的分页关系对象,原生Ruby数组没有Kaminari注入的这些分页方法,非用户场景下传入空数组时,辅助方法内部无法正确解析分页信息,最终抛出方法不存在的错误。
额外提示:原代码中where条件的写法存在语法隐患,[user_id = ?, current_user.id]会被Ruby解析为给局部变量user_id赋值,而非传入SQL条件字符串,建议改成哈希写法避免SQL生成异常。
修复方案
可根据业务场景二选一:
- 方案1:保证传入paginate的对象始终是Kaminari分页对象
把非用户场景下的空数组替换为ActiveRecord的空关系分页结果,和正常分支返回的数据类型保持一致:if user? @carts = Cart.order(created_at: :desc).where(user_id: current_user.id).page(params[:page]) else # per_page参数和全局配置的每页条数保持一致即可 @carts = Cart.none.page(params[:page]) end - 方案2:视图层增加渲染判断
如果非用户场景下本身不需要展示分页控件,直接在视图层加判断,只有对象支持分页方法时才渲染分页条:<% if @carts.respond_to?(:total_pages) %> <%= paginate @carts %> <% end %>
内容的提问来源于stack exchange,提问作者Jerome
相关产品推荐
相关产品推荐

