2017-04-26 114 views
0

我稍微修改版本雷找到哪個頁面我的紀錄是(原代碼是在這裏:https://github.com/kaminari/kaminari/wiki/FAQ#how-can-i-know-which-page-a-record-is-on):爲什麼.order不會在我的查詢中執行?

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不執行一些奇怪的原因。這裏是軌道控制檯中的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

count ing時,Rails忽略order子句。

而不是依靠Rails的count方法,嘗試手動計數:

data.where("#{column} #{operator} ?", read_attribute(column)) 
     .order("#{column} #{order} #{nulls_last}") 
     .select('COUNT(*) c').first.c.to_f/per 
相關問題