peiji-san 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,22 +1,42 @@
1
1
  = Peiji-San
2
2
 
3
- Peiji-San uses named scopes to create a thin pagination layer.
3
+ Peiji-San uses scopes to create a thin pagination layer.
4
4
 
5
- Model:
5
+ We try to stay out of the way of your application as much as possible. That's
6
+ why you need to include Peiji in the places where you actually use it.
6
7
 
7
8
  class Member < ActiveRecord::Base
8
9
  extend PeijiSan
9
10
  self.entries_per_page = 32
10
11
  end
11
12
 
12
- Controller:
13
+ After that a special extended scope is defined on the model and you will be
14
+ able to select a collection that contains only records on that page.
13
15
 
14
16
  @collection = Member.active.page(2)
15
17
 
16
- View:
18
+ In the view you can either build your own links to the pages or you can use
19
+ the helpers shipped with Peiji. Like with the model extension the view
20
+ helpers aren't defined by default, you will need to include them in another
21
+ helper class.
22
+
23
+ class ApplicationHelper
24
+ include PeijiSan::ViewHelper
25
+ end
26
+
27
+ After that the helpers will be usable in your view.
17
28
 
18
29
  <% if @collection.page_count > 1 %>
19
- <% pages_to_link_to(@collection).each do |page %>
30
+ <% pages_to_link_to(@collection).each do |page| %>
20
31
  <%= page.is_a?(String) ? page : link_to_page(page, @collection) %>
21
32
  <% end %>
22
33
  <% end %>
34
+
35
+ == Rails 2.3 and earlier
36
+
37
+ The latest version of Peiji only works in Rails 3 because of extensive
38
+ changes to the scope API. However, earlier version work just fine in
39
+ Rails 2.3. Rails 3 support starts at version 1.0, so put the following
40
+ in environment.rb:
41
+
42
+ config.gem "peiji-san", :lib => "peiji_san", :version => "< 1.0"
data/TODO CHANGED
@@ -1,2 +1 @@
1
- * Merge Scope and Array methods
2
1
  * Make it possible to use this pattern: http://www.percona.com/ppc2009/PPC2009_mysql_pagination.pdf
data/VERSION.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
- :major: 0
3
- :minor: 1
4
- :patch: 1
2
+ :patch: 0
3
+ :major: 1
4
+ :build:
5
+ :minor: 0
File without changes
@@ -1,11 +1,13 @@
1
1
  module PeijiSan
2
- # Include this module into your view helper module, for instance
3
- # ApplicationController, for super paginating cow powers.
4
- #
5
- # Optionally define the peiji_san_options method in your helper to override
2
+ # Optionally defines the peiji_san_options method in your helper to override
6
3
  # the default options.
7
4
  #
8
- # Example:
5
+ # Include the PeijiSan::ViewHelper into one of your view helpers to acquire
6
+ # PeijiSan superpowers in your view.
7
+ #
8
+ # class ApplicationHelper
9
+ # include PeijiSan::ViewHelper
10
+ # end
9
11
  #
10
12
  # @collection = Member.active.page(2)
11
13
  #
@@ -17,7 +19,7 @@ module PeijiSan
17
19
  DEFAULT_PEIJI_SAN_OPTIONS = {
18
20
  # For link_to_page
19
21
  :page_parameter => :page,
20
- :anchor => :explore,
22
+ :anchor => nil,
21
23
  :current_class => :current,
22
24
  # For pages_to_link_to
23
25
  :max_visible => 11,
@@ -65,8 +67,6 @@ module PeijiSan
65
67
  # The separator string used to indicate a range between the first or last
66
68
  # page and the ones surrounding the current page.
67
69
  #
68
- # Example:
69
- #
70
70
  # collection = Model.all.page(40)
71
71
  # collection.page_count # => 80
72
72
  #
data/lib/peiji_san.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # Peiji-San uses named scopes to create a thin pagination layer.
2
2
  #
3
- # Example:
4
- #
5
3
  # class Member < ActiveRecord::Base
6
4
  # extend PeijiSan
7
5
  # self.entries_per_page = 32
@@ -13,16 +11,18 @@
13
11
  #
14
12
  # Which will return 32 records with an offset of 32, as that's the second page.
15
13
  #
16
- # See PeijiSan::PageScope and PeijiSan::ViewHelper for more info.
14
+ # See PeijiSan::PaginationMethods and PeijiSan::ViewHelper for more info.
17
15
  module PeijiSan
18
- class PageScope < ActiveRecord::NamedScope::Scope
19
- attr_reader :current_page
20
-
21
- def initialize(proxy_scope, options)
22
- @current_page = (options[:page].blank? ? 1 : options[:page]).to_i
23
- @entries_per_page = options[:entries_per_page]
24
- super(proxy_scope, :offset => ((@current_page - 1) * @entries_per_page), :limit => @entries_per_page)
25
- end
16
+ ENTRIES_PER_PAGE = 32
17
+
18
+ # The page scope is extended with the PaginationMethods. This means that all
19
+ # methods defined on this module will be available on the resulting
20
+ # collection.
21
+ #
22
+ # collection = Member.active.page(1)
23
+ # collection.has_next_page?
24
+ module PaginationMethods
25
+ attr_accessor :current_page, :entries_per_page, :scope_without_pagination
26
26
 
27
27
  # Returns whether or not the given page is the current page.
28
28
  def current_page?(page)
@@ -53,13 +53,13 @@ module PeijiSan
53
53
 
54
54
  # Returns the row count for all the rows that would match the current
55
55
  # scope, so not only on the current page.
56
- def count
57
- @proxy_scope.count
56
+ def unpaged_count
57
+ scope_without_pagination.count
58
58
  end
59
59
 
60
60
  # Returns the number of pages for the current scope.
61
61
  def page_count
62
- (count.to_f / @entries_per_page).ceil
62
+ (unpaged_count.to_f / @entries_per_page).ceil
63
63
  end
64
64
  end
65
65
 
@@ -67,7 +67,7 @@ module PeijiSan
67
67
  #
68
68
  # class Member < ActiveRecord::Base
69
69
  # extend PeijiSan
70
- # entries_per_page 32
70
+ # self.entries_per_page = 32
71
71
  # end
72
72
  def entries_per_page=(entries)
73
73
  @entries_per_page = entries
@@ -77,7 +77,7 @@ module PeijiSan
77
77
  #
78
78
  # class Member < ActiveRecord::Base
79
79
  # extend PeijiSan
80
- # entries_per_page 32
80
+ # self.entries_per_page = 32
81
81
  # end
82
82
  # Member.entries_per_page #=> 32
83
83
  def entries_per_page
@@ -90,7 +90,7 @@ module PeijiSan
90
90
  #
91
91
  # class Member < ActiveRecord::Base
92
92
  # extend PeijiSan
93
- # entries_per_page 32
93
+ # self.entries_per_page = 32
94
94
  # end
95
95
  #
96
96
  # This adds <tt>{ :limit => 32, :offset => 0 }</tt> to the scope:
@@ -105,20 +105,16 @@ module PeijiSan
105
105
  # second argument:
106
106
  #
107
107
  # Member.page(2, 5) # Page 2, 5 entries
108
- def page(page, entries_per_page = nil)
109
- scopes[:page].call(self, page, entries_per_page)
110
- end
111
-
112
- # Defines the page named_scope when it extends a model class.
113
- #
114
- # Member.respond_to? :page # => false
115
- #
116
- # class Member < ActiveRecord::Base
117
- # extend PeijiSan
118
- # end
119
- #
120
- # Member.respond_to? :page # => true
121
- def self.extended(klass)
122
- klass.scopes[:page] = lambda { |parent_scope, *args| PageScope.new(parent_scope, :page => args[0], :entries_per_page => args[1] || klass.entries_per_page) }
108
+ def page(page, entries_per_page=nil)
109
+ page = page.blank? ? 1 : page.to_i
110
+ entries_per_page = entries_per_page || self.entries_per_page || ENTRIES_PER_PAGE
111
+
112
+ entries = scoped
113
+ entries.extend(PeijiSan::PaginationMethods)
114
+ entries.current_page = page
115
+ entries.entries_per_page = entries_per_page
116
+ entries.scope_without_pagination = scoped
117
+
118
+ entries.limit(entries_per_page).offset((page - 1) * entries_per_page)
123
119
  end
124
120
  end
@@ -0,0 +1,344 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>Module: PeijiSan::PaginationMethods</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="classHeader">
50
+ <table class="header-table">
51
+ <tr class="top-aligned-row">
52
+ <td><strong>Module</strong></td>
53
+ <td class="class-name-in-header">PeijiSan::PaginationMethods</td>
54
+ </tr>
55
+ <tr class="top-aligned-row">
56
+ <td><strong>In:</strong></td>
57
+ <td>
58
+ <a href="../../files/lib/peiji_san_rb.html">
59
+ lib/peiji_san.rb
60
+ </a>
61
+ <br />
62
+ </td>
63
+ </tr>
64
+
65
+ </table>
66
+ </div>
67
+ <!-- banner header -->
68
+
69
+ <div id="bodyContent">
70
+
71
+
72
+
73
+ <div id="contextContent">
74
+
75
+ <div id="description">
76
+ <p>
77
+ The page scope is extended with the <a
78
+ href="PaginationMethods.html">PaginationMethods</a>. This means that all
79
+ methods defined on this module will be available on the resulting
80
+ collection.
81
+ </p>
82
+ <pre>
83
+ collection = Member.active.page(1)
84
+ collection.has_next_page?
85
+ </pre>
86
+
87
+ </div>
88
+
89
+
90
+ </div>
91
+
92
+ <div id="method-list">
93
+ <h3 class="section-bar">Methods</h3>
94
+
95
+ <div class="name-list">
96
+ <a href="#M000007">current_page?</a>&nbsp;&nbsp;
97
+ <a href="#M000008">has_next_page?</a>&nbsp;&nbsp;
98
+ <a href="#M000009">has_previous_page?</a>&nbsp;&nbsp;
99
+ <a href="#M000010">next_page</a>&nbsp;&nbsp;
100
+ <a href="#M000013">page_count</a>&nbsp;&nbsp;
101
+ <a href="#M000011">previous_page</a>&nbsp;&nbsp;
102
+ <a href="#M000012">unpaged_count</a>&nbsp;&nbsp;
103
+ </div>
104
+ </div>
105
+
106
+ </div>
107
+
108
+
109
+ <!-- if includes -->
110
+
111
+ <div id="section">
112
+
113
+
114
+
115
+
116
+
117
+ <div id="attribute-list">
118
+ <h3 class="section-bar">Attributes</h3>
119
+
120
+ <div class="name-list">
121
+ <table>
122
+ <tr class="top-aligned-row context-row">
123
+ <td class="context-item-name">current_page</td>
124
+ <td class="context-item-value">&nbsp;[RW]&nbsp;</td>
125
+ <td class="context-item-desc"></td>
126
+ </tr>
127
+ <tr class="top-aligned-row context-row">
128
+ <td class="context-item-name">entries_per_page</td>
129
+ <td class="context-item-value">&nbsp;[RW]&nbsp;</td>
130
+ <td class="context-item-desc"></td>
131
+ </tr>
132
+ <tr class="top-aligned-row context-row">
133
+ <td class="context-item-name">scope_without_pagination</td>
134
+ <td class="context-item-value">&nbsp;[RW]&nbsp;</td>
135
+ <td class="context-item-desc"></td>
136
+ </tr>
137
+ </table>
138
+ </div>
139
+ </div>
140
+
141
+
142
+
143
+ <!-- if method_list -->
144
+ <div id="methods">
145
+ <h3 class="section-bar">Public Instance methods</h3>
146
+
147
+ <div id="method-M000007" class="method-detail">
148
+ <a name="M000007"></a>
149
+
150
+ <div class="method-heading">
151
+ <a href="#M000007" class="method-signature">
152
+ <span class="method-name">current_page?</span><span class="method-args">(page)</span>
153
+ </a>
154
+ </div>
155
+
156
+ <div class="method-description">
157
+ <p>
158
+ Returns whether or not the given page is the current page.
159
+ </p>
160
+ <p><a class="source-toggle" href="#"
161
+ onclick="toggleCode('M000007-source');return false;">[Source]</a></p>
162
+ <div class="method-source-code" id="M000007-source">
163
+ <pre>
164
+ <span class="ruby-comment cmt"># File lib/peiji_san.rb, line 30</span>
165
+ 30: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">current_page?</span>(<span class="ruby-identifier">page</span>)
166
+ 31: <span class="ruby-ivar">@current_page</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">page</span>
167
+ 32: <span class="ruby-keyword kw">end</span>
168
+ </pre>
169
+ </div>
170
+ </div>
171
+ </div>
172
+
173
+ <div id="method-M000008" class="method-detail">
174
+ <a name="M000008"></a>
175
+
176
+ <div class="method-heading">
177
+ <a href="#M000008" class="method-signature">
178
+ <span class="method-name">has_next_page?</span><span class="method-args">()</span>
179
+ </a>
180
+ </div>
181
+
182
+ <div class="method-description">
183
+ <p>
184
+ Returns whether or not there is a next page for the current scope.
185
+ </p>
186
+ <p><a class="source-toggle" href="#"
187
+ onclick="toggleCode('M000008-source');return false;">[Source]</a></p>
188
+ <div class="method-source-code" id="M000008-source">
189
+ <pre>
190
+ <span class="ruby-comment cmt"># File lib/peiji_san.rb, line 35</span>
191
+ 35: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">has_next_page?</span>
192
+ 36: <span class="ruby-ivar">@current_page</span> <span class="ruby-operator">&lt;</span> <span class="ruby-identifier">page_count</span>
193
+ 37: <span class="ruby-keyword kw">end</span>
194
+ </pre>
195
+ </div>
196
+ </div>
197
+ </div>
198
+
199
+ <div id="method-M000009" class="method-detail">
200
+ <a name="M000009"></a>
201
+
202
+ <div class="method-heading">
203
+ <a href="#M000009" class="method-signature">
204
+ <span class="method-name">has_previous_page?</span><span class="method-args">()</span>
205
+ </a>
206
+ </div>
207
+
208
+ <div class="method-description">
209
+ <p>
210
+ Returns whether or not there is a previous page for the current scope.
211
+ </p>
212
+ <p><a class="source-toggle" href="#"
213
+ onclick="toggleCode('M000009-source');return false;">[Source]</a></p>
214
+ <div class="method-source-code" id="M000009-source">
215
+ <pre>
216
+ <span class="ruby-comment cmt"># File lib/peiji_san.rb, line 40</span>
217
+ 40: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">has_previous_page?</span>
218
+ 41: <span class="ruby-ivar">@current_page</span> <span class="ruby-operator">!=</span> <span class="ruby-value">1</span>
219
+ 42: <span class="ruby-keyword kw">end</span>
220
+ </pre>
221
+ </div>
222
+ </div>
223
+ </div>
224
+
225
+ <div id="method-M000010" class="method-detail">
226
+ <a name="M000010"></a>
227
+
228
+ <div class="method-heading">
229
+ <a href="#M000010" class="method-signature">
230
+ <span class="method-name">next_page</span><span class="method-args">()</span>
231
+ </a>
232
+ </div>
233
+
234
+ <div class="method-description">
235
+ <p>
236
+ Returns the next page number if there is a next page, returns <tt>nil</tt>
237
+ otherwise.
238
+ </p>
239
+ <p><a class="source-toggle" href="#"
240
+ onclick="toggleCode('M000010-source');return false;">[Source]</a></p>
241
+ <div class="method-source-code" id="M000010-source">
242
+ <pre>
243
+ <span class="ruby-comment cmt"># File lib/peiji_san.rb, line 46</span>
244
+ 46: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">next_page</span>
245
+ 47: <span class="ruby-ivar">@current_page</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">has_next_page?</span>
246
+ 48: <span class="ruby-keyword kw">end</span>
247
+ </pre>
248
+ </div>
249
+ </div>
250
+ </div>
251
+
252
+ <div id="method-M000013" class="method-detail">
253
+ <a name="M000013"></a>
254
+
255
+ <div class="method-heading">
256
+ <a href="#M000013" class="method-signature">
257
+ <span class="method-name">page_count</span><span class="method-args">()</span>
258
+ </a>
259
+ </div>
260
+
261
+ <div class="method-description">
262
+ <p>
263
+ Returns the number of pages for the current scope.
264
+ </p>
265
+ <p><a class="source-toggle" href="#"
266
+ onclick="toggleCode('M000013-source');return false;">[Source]</a></p>
267
+ <div class="method-source-code" id="M000013-source">
268
+ <pre>
269
+ <span class="ruby-comment cmt"># File lib/peiji_san.rb, line 63</span>
270
+ 63: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">page_count</span>
271
+ 64: (<span class="ruby-identifier">unpaged_count</span>.<span class="ruby-identifier">to_f</span> <span class="ruby-operator">/</span> <span class="ruby-ivar">@entries_per_page</span>).<span class="ruby-identifier">ceil</span>
272
+ 65: <span class="ruby-keyword kw">end</span>
273
+ </pre>
274
+ </div>
275
+ </div>
276
+ </div>
277
+
278
+ <div id="method-M000011" class="method-detail">
279
+ <a name="M000011"></a>
280
+
281
+ <div class="method-heading">
282
+ <a href="#M000011" class="method-signature">
283
+ <span class="method-name">previous_page</span><span class="method-args">()</span>
284
+ </a>
285
+ </div>
286
+
287
+ <div class="method-description">
288
+ <p>
289
+ Returns the previous page number if there is a previous page, returns
290
+ <tt>nil</tt> otherwise.
291
+ </p>
292
+ <p><a class="source-toggle" href="#"
293
+ onclick="toggleCode('M000011-source');return false;">[Source]</a></p>
294
+ <div class="method-source-code" id="M000011-source">
295
+ <pre>
296
+ <span class="ruby-comment cmt"># File lib/peiji_san.rb, line 52</span>
297
+ 52: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">previous_page</span>
298
+ 53: <span class="ruby-ivar">@current_page</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">has_previous_page?</span>
299
+ 54: <span class="ruby-keyword kw">end</span>
300
+ </pre>
301
+ </div>
302
+ </div>
303
+ </div>
304
+
305
+ <div id="method-M000012" class="method-detail">
306
+ <a name="M000012"></a>
307
+
308
+ <div class="method-heading">
309
+ <a href="#M000012" class="method-signature">
310
+ <span class="method-name">unpaged_count</span><span class="method-args">()</span>
311
+ </a>
312
+ </div>
313
+
314
+ <div class="method-description">
315
+ <p>
316
+ Returns the row count for all the rows that would match the current scope,
317
+ so not only on the current page.
318
+ </p>
319
+ <p><a class="source-toggle" href="#"
320
+ onclick="toggleCode('M000012-source');return false;">[Source]</a></p>
321
+ <div class="method-source-code" id="M000012-source">
322
+ <pre>
323
+ <span class="ruby-comment cmt"># File lib/peiji_san.rb, line 58</span>
324
+ 58: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">unpaged_count</span>
325
+ 59: <span class="ruby-identifier">scope_without_pagination</span>.<span class="ruby-identifier">count</span>
326
+ 60: <span class="ruby-keyword kw">end</span>
327
+ </pre>
328
+ </div>
329
+ </div>
330
+ </div>
331
+
332
+
333
+ </div>
334
+
335
+
336
+ </div>
337
+
338
+
339
+ <div id="validator-badges">
340
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
341
+ </div>
342
+
343
+ </body>
344
+ </html>