新手问题 will_paginate 分页问题,如何对数组分页

perky123 · 2016年01月12日 · 最后由 fayake 回复于 2016年01月14日 · 2926 次阅读

由于涉及到的表比较多,所以写了如下的查询语句,现想对结果进行分页显示

@store_cards = StoreCard.where(store_id: current_member.store_id).order(id: :asc).map do |sp|
    sp.card
end

尝试过直接这样写

@store_cards = StoreCard.where(store_id: current_member.store_id).order(id: :asc).map do |sp|
    sp.card
end.page(params[:page]).per(10)

会出现

undefined method `page' for #Array:0x00000006e7db40 错误

也尝试过这样写,可以实现分页,但查询量增加了一倍,想问问大家有没有更好的方法。

store_card_ids = StoreCard.where(store_id: current_member.store_id).order(id: :asc).map do |sp|
sp.card_id
end
@store_cards = Card.where(id: store_card_ids).page(params[:page]).per(10)

还是说 map 方法处理过之后返回值并不是数组。。

map 返回的是数组。如果我记得没错的话,page 是直接生成 sql 语句直接操作数据库,不能直接对数组进行分页的

@kai209209 谢谢,用 kaminari 这个 gem 可以了 https://github.com/amatsuda/kaminari

@paginatable_array = Kaminari.paginate_array(my_array_object).page(params[:page]).per(10)

这样,非常感谢

如果数组数据很大的话,就会浪费内存

为什么要这么写……

@store_cards = StoreCard.where(store_id: current_member.store_id).order(id: :asc).page(params[:page]).per(10).select(:card)

不就好了?

如果 card 是方法而不是字段的话改成 map(&:card)。

#6 楼 @msg7086 card 不是字段,也不是方法,store_card 是一个关联表,关联 store 和 card 表。 我的思路是从 store_card 里先找出来所有的当前 store 的 card_id,然后去查 card 表,然后显示所有当前 store 中 cards 的信息

store_cards = StoreCard.where(store_id: current_member.store_id).order(id: :asc).map do |sp|
  sp.card
end
@store_cards = Kaminari.paginate_array(store_cards).page(params[:page]).per(10)

改成了这样,map 返回的是一个数组,数组中的每一个元素是 card 表中的每一个实例。这么描述对么~谢谢。

#5 楼 @pathbox 分页这个不应该是每一页要多少组数据,然后会去查多少组数据么,我不是很了解,我去查查看。。

楼主,

我假设你的 model 结构是这样:

class StoreCard
  has_many :cards
end
class Card
    belongs_to :store_card
end

方案一

把 sql 写好了,就可以避免对数组分组:

# 1. 筛出 store card 的 id
store_card_ids = StoreCard.where(store_id: current_member.store_id).pluck(:id)

# 2. 通过 in 查询拿到 card,然后根据  store_card_id 对 card 做排序
@cards = Card.where(store_card_id: store_card_ids).order("store_card_id ASC").page(params[:page])

方案 2 给表 cards 创建一个冗余字段 store_id,并加上索引

代码会变的更加简洁:

@cards = Card.where(store_id: current_member.store_id).page(params[:page])

避免了

  1. 一堆 sql 查询
  2. 无谓的 database IO
  3. 无谓的 Ruby 对象实例化和排序
10 楼 已删除

#9 楼 @xiaoronglv 非常感谢,确实应该完善一下表结构。一直在想怎么查询,怎么分页,忽略了这个。

关联表我记得是要用 has_and_belongs_to_many 之类的吧。不太记得了。

#12 楼 @msg7086 嗯,是已经关联好的表,这个是 controller 里的查询语句

#13 楼 @perky123 (2..100).to_a.paginate({page:1,per_page:3})

需要 登录 后方可回复, 如果你还没有账号请 注册新账号