Class: MultiModelPaginator::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/multi_model_paginator.rb

Instance Method Summary collapse

Constructor Details

#initialize(per, page) ⇒ Builder



28
29
30
31
32
33
# File 'lib/multi_model_paginator.rb', line 28

def initialize(per, page)
  @query_list = []
  @per = per
  @page = page.to_i
  @list = []
end

Instance Method Details

#add(query, select: nil, count: nil) ⇒ Object



35
36
37
# 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_allObject



39
40
41
# File 'lib/multi_model_paginator.rb', line 39

def count_all
  @query_list.map(&:count).sum
end

#resultObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# 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