Kaminari:定制模型的分页

时间:2017-01-14 03:52:46

标签: ruby-on-rails activerecord pagination kaminari

我有一个自定义模型(不是由数据库下的任何表映射)。这个自定义模型只是联合许多其他表的数据的结果。我想用kaminari作为分页。

例如:

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

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

  = paginate @custom_models

当我运行时,我遇到异常:

  

数组的未定义方法`total_pages':0x007fb4dde63c70

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

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

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

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

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

感谢

1 个答案:

答案 0 :(得分:2)

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

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

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

但我认为最好的方法是控制模型中的偏移/限制(分页)。为了向您展示如何执行此操作,使代码生成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来注入它们。