我稍微修改了Kaminari的版本以找到我的记录在哪个页面(原始代码在这里:https://github.com/kaminari/kaminari/wiki/FAQ#how-can-i-know-which-page-a-record-is-on):
module KaminariHelper
extend ActiveSupport::Concern
# Detecting page number in pagination. This method allows you to specify column name, order,
# items per page and collection ids to filter specific collection.
#
# Options:
# * :by - specifies the column name. Defaults to :id.
# * :order - specifies the order in DB. Defaults to :asc.
# * :per - specifies amount of items per page. Defaults to object model's default_per_page.
# * :nulls_last - if set to true, will add "nulls last" into the order.
# * :collection_ids - array of ids for the collection of current class to search position in specific collection.
# If it's ommited then search is done across all objects of current object's model.
#
def page_num(options = {})
column = options[:by] || :id
order = options[:order] || :asc
per = options[:per] || self.class.default_per_page
nulls_last = options[:nulls_last] == true ? "nulls last" : ""
operator = (order == :asc ? "<=" : ">=")
data = if options[:collection_ids].present?
self.class.where(id: options[:collection_ids])
else
self.class
end
# 1. Get a count number of all the results that are listed before the given record/value.
# 2. Divide the count by default_per_page or per number given as an option.
# 3. Ceil the number to get a proper page number that the record/value is on.
(
data.where("#{column} #{operator} ?", read_attribute(column))
.order("#{column} #{order} #{nulls_last}").count.to_f / per
).ceil
end
end
然而,当我测试它时出于一些奇怪的原因.order
似乎没有被执行。这是rails console中的sql输出:
2.3.1 :005 > email.page_num(by: :sent_at, order: :desc, per: 25, collection_ids: user.emails.ids, nulls_last: true)
(1.1ms) SELECT "emails"."id" FROM "emails" WHERE "emails"."deleted_at" IS NULL
AND "emails"."user_id" = $1 [["user_id", 648]]
(1.5ms) SELECT COUNT(*) FROM "emails" WHERE "emails"."deleted_at" IS NULL AND
"emails"."id" IN (35946, 41741) AND (sent_at >= '2016-01-22 14:04:26.700352')
=> 13
为什么.order
未在最终的SQL查询中应用?有没有办法执行它?否则代码没有意义,因为无法保证它会给我正确的页码。
答案 0 :(得分:0)
Rails在order
时忽略了count
子句。
而不是依赖于Rails&#39; count
方法,尝试手动计算:
data.where("#{column} #{operator} ?", read_attribute(column))
.order("#{column} #{order} #{nulls_last}")
.select('COUNT(*) c').first.c.to_f / per