Browse Source

pagination: fix pagination module

Previous implementation was not really compatible with active record
models. It fixes it with scope instead of methods.
Arthur POULET 2 years ago
parent
commit
51a6999a47
2 changed files with 37 additions and 25 deletions
  1. 7
    8
      app/models/paginated.rb
  2. 30
    17
      test/models/paginated_test.rb

+ 7
- 8
app/models/paginated.rb View File

@@ -1,13 +1,12 @@
1 1
 module Paginated
2 2
   DEFAULT_COUNT_BY_PAGE = 10
3
-  # can be overwritten
4
-  def count_by_page
5
-    DEFAULT_COUNT_BY_PAGE
6
-  end
7 3
 
8
-  def paginate(params)
9
-    page = (params.fetch :page, 0).to_i
10
-    start = page * count_by_page
11
-    offset(start).limit(count_by_page)
4
+  def self.included(includer)
5
+    includer.scope :paginate, -> (params) {
6
+      count_by_page = includer.respond_to?(:count_by_page) ? includer.count_by_page : DEFAULT_COUNT_BY_PAGE
7
+      page = (params.fetch :page, 0).to_i
8
+      start = page * count_by_page
9
+      offset(start).limit(count_by_page)
10
+    }
12 11
   end
13 12
 end

+ 30
- 17
test/models/paginated_test.rb View File

@@ -1,33 +1,42 @@
1 1
 require "test_helper"
2 2
 require_relative "../../app/models/paginated"
3 3
 
4
+# fake model, fake behavior, etc.
4 5
 class FakePaginated
5
-  include Paginated
6 6
   DATA = ("a".."z").to_a
7 7
 
8 8
   # fake inspection
9
-  attr_reader :data
9
+  def self.data
10
+    @@data
11
+  end
10 12
 
11 13
   # fake a model
12
-  def initialize
13
-    @data = DATA
14
+  def self.scope(scope_name, callback)
15
+    define_singleton_method scope_name, callback
14 16
   end
15 17
 
16 18
   # fake a model
17
-  def offset(start)
18
-    @data = @data[start..]
19
+  def self.reset!
20
+    @@data = DATA
21
+  end
22
+
23
+  # fake a model
24
+  def self.offset(start)
25
+    @@data = @@data[start..]
19 26
     self
20 27
   end
21 28
 
22 29
   # fake a model
23
-  def limit(count)
24
-    @data = @data[...count]
30
+  def self.limit(count)
31
+    @@data = @@data[...count]
25 32
     self
26 33
   end
27 34
 
28
-  def count_by_page
35
+  def self.count_by_page
29 36
     3
30 37
   end
38
+
39
+  include Paginated
31 40
 end
32 41
 
33 42
 class PaginatedTest < ActiveSupport::TestCase
@@ -36,19 +45,23 @@ class PaginatedTest < ActiveSupport::TestCase
36 45
   end
37 46
 
38 47
   test "paginated with placeholder" do
39
-    test_empty_params = FakePaginated.new.paginate({})
40
-    assert_valid_pagination test_empty_params, count: FakePaginated.new.count_by_page
48
+    FakePaginated.reset!
49
+    test_empty_params = FakePaginated.paginate({})
50
+    assert_valid_pagination test_empty_params, count: FakePaginated.count_by_page
41 51
     assert_equal %w[a b c], test_empty_params.data
42 52
 
43
-    test_valid_params = FakePaginated.new.paginate({ page: 1 })
44
-    assert_valid_pagination test_valid_params, count: FakePaginated.new.count_by_page
53
+    FakePaginated.reset!
54
+    test_valid_params = FakePaginated.paginate({ page: 1 })
55
+    assert_valid_pagination test_valid_params, count: FakePaginated.count_by_page
45 56
     assert_equal %w[d e f], test_valid_params.data
46
-    test_valid_params = FakePaginated.new.paginate({ page: 4 })
47
-    assert_valid_pagination test_valid_params, count: FakePaginated.new.count_by_page
57
+    FakePaginated.reset!
58
+    test_valid_params = FakePaginated.paginate({ page: 4 })
59
+    assert_valid_pagination test_valid_params, count: FakePaginated.count_by_page
48 60
     assert_equal %w[m n o], test_valid_params.data
49 61
 
50
-    test_invalid_params = FakePaginated.new.paginate({ page: "what" })
51
-    assert_valid_pagination test_invalid_params, count: FakePaginated.new.count_by_page
62
+    FakePaginated.reset!
63
+    test_invalid_params = FakePaginated.paginate({ page: "what" })
64
+    assert_valid_pagination test_invalid_params, count: FakePaginated.count_by_page
52 65
     assert_equal %w[a b c], test_invalid_params.data
53 66
   end
54 67
 end

Loading…
Cancel
Save