我有一个自定义模型(不是由数据库下的任何表映射)。这个自定义模型只是联合许多其他表的数据的结果。我想用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查询并使用offset
和limit
关键字自行分页。
例如,我返回25条记录,默认的Kaminari每页显示25条记录,所以我只能看到1页。我可以查询返回总的必要记录(例如1000条记录),但我不知道如何让Kaminari理解这一点并向我展示足够的页面。
感谢
答案 0 :(得分:2)
首先,我假设fetch_all_items
。是一个数组。
您可以在控制器上插入分页,但这意味着数据库将加载整个集合,然后使用数组分页方法过滤结果。
@custom_models = Kaminari.paginate_array(fetch_all_items).page(params[:page])
但我认为最好的方法是控制模型中的偏移/限制(分页)。为了向您展示如何执行此操作,使代码生成fetch_all_items
。
更新 - 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_page
,prev_page
,我不知道。使用相同的块items.class.module_eval
来注入它们。