Kaminari:自定义模型的分页

Kaminari: pagination for custom model

我有一个自定义模型(未通过数据库下的任何 table 进行映射)。这个自定义模型只是结合了许多其他 table 的数据的结果。我想用 kaminari 来分页。

例如:

def index
   @custom_models = find_all_items # result is an array
   render
end

然后我在视图中对这些项目进行分页:

  = paginate @custom_models

当我运行这个时候,我遇到异常:

undefined method `total_pages' for Array:0x007fb4dde63c70

我的问题是:如何将 Kaminari 用于自定义模型文件。

@编辑 我现在可以使用 Kaminari,只需使用这一行:

  @custom_models = Kaminari.paginate_array(@custom_models)
                  .page(params[:page]).per(params[:per_page])

但现在我遇到了问题:因为这是自定义模型,所以我正在使用自定义查询。我使用原始 sql 查询并使用 offsetlimit 关键字自行分页。

比如我return25条记录,Kaminari默认每页显示25条记录所以我只能看到1页。我可以查询 return 总的必要记录(例如 1000 条记录),但我不知道如何让 Kaminari 理解这一点并向我展示足够的页面。

谢谢

首先,我假设 fetch_all_items. 是一个数组。

您可以在控制器中插入分页,但这意味着数据库将加载整个集合,然后使用数组分页方法过滤结果。

@custom_models =  Kaminari.paginate_array(fetch_all_items).page(params[:page])

但我认为最好的方法是在模型中控制 offset/limit(分页)。为了向您展示如何做到这一点,拥有生成 fetch_all_items.

的代码会很有帮助

您可以在 Kaminari wiki page

中找到更多信息

更新 - hacky!!!

所以,现在我们正在考虑不同的事情。不能 100% 确定这就足够了,但如果您想在模型中进行激进和分页,这应该是方法:

在你的模型中,你应该有这样的东西(当然,你会根据你的需要进行调整):

def fetch_all_items(page, per_page)
    offset = page*per_page
    items = SomeSqlMethod("select .... offset #{offset}, limit #{per_page}") # your sql statement
    total_rows = SomeSqlMethod("select count(..) ....") # to get the total number of records
    total_pages = (total_rows.to_f / per_page).ceil # to get the total pages
    items.class.module_eval { 
        attr_accessor :total_pages, :current_page
    } # to add some variables to make Kaminari happy
    items.total_pages = total_pages
    items.current_page = page
    items # to return this
end

那么,在你的控制器中,你应该有:

@custom_model = fetch_all_items(params[:page].to_i, params[:per_page].to_i) # cast to integer to avoid injections and misfunctions

除了:total_pages, :current_page,Kaminari可能还想要其他一些变量,比如next_pageprev_page,我不知道。使用相同的块 items.class.module_eval 来注入它们。