class MultiModelPaginator::Builder

Public Class Methods

new(per, page) click to toggle source
# File lib/multi_model_paginator.rb, line 28
def initialize(per, page)
  @query_list = []
  @per = per
  @page = page.to_i
  @list = []
end

Public Instance Methods

add(query, select: nil, count: nil) click to toggle source
# File lib/multi_model_paginator.rb, line 35
def add(query, select: nil, count: nil)
  @query_list.push(QueryStruct.new(query, select, count))
end
count_all() click to toggle source
# File lib/multi_model_paginator.rb, line 39
def count_all
  @query_list.map(&:count).sum
end
result() click to toggle source
# File lib/multi_model_paginator.rb, line 43
def result
  remain = @per
  position = @page * @per
  @query_list.reduce([]) do |accumulator, query_struct|
    prev_total_count = @query_list.reduce(0) { |a, q| q == query_struct ? (break(a)) : (a += q.count) }
    current_range = (prev_total_count...(prev_total_count + query_struct.count))
    if !current_range.include?(position)
      next(accumulator)
    end
    prev_query_offset = current_range.first
    # テーブルt1に6レコード, テーブルt2に10レコードある場合、per:10で読んだ時にpage:2はテーブルt2の5個目が先頭になる
    # |t1:......|t2:....[.].......|
    offset = (@page * @per) - prev_query_offset
    offset = 0 if offset.negative?
    list = query_struct.with_select.limit(@per).offset(offset).to_a.first(remain)
    accumulator.concat(list)
    remain = remain - list.size
    if remain == 0
      break(accumulator)
    else
      position = prev_total_count + query_struct.count
      next(accumulator)
    end
  end
end