Skip to content

Commit 2c5bb35

Browse files
committed
Code re-organization
Signed-off-by: David Celis <[email protected]>
1 parent f6e0498 commit 2c5bb35

File tree

6 files changed

+145
-113
lines changed

6 files changed

+145
-113
lines changed

lib/api-pagination.rb

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,4 @@
1+
require 'api-pagination/hooks'
12
require 'api-pagination/version'
23

3-
module ApiPagination
4-
protected
5-
def paginate(scope)
6-
links = (headers['Link'] || "").split(',').map(&:strip)
7-
8-
scope = instance_variable_get(:"@#{scope}")
9-
url = request.original_url.sub(/\?.*$/, '')
10-
pages = {}
11-
12-
unless scope.first_page?
13-
pages[:first] = 1
14-
pages[:prev] = scope.current_page - 1
15-
end
16-
17-
unless scope.last_page?
18-
pages[:last] = scope.total_pages
19-
pages[:next] = scope.current_page + 1
20-
end
21-
22-
pages.each do |k, v|
23-
new_params = request.query_parameters.merge(:page => v)
24-
links << %(<#{url}?#{new_params.to_param}>; rel="#{k}")
25-
end
26-
27-
headers['Link'] = links.join(', ') unless links.empty?
28-
end
29-
end
30-
31-
ActionController::Base.send(:include, ApiPagination) if defined?(ActionController::Base)
32-
ActionController::API.send(:include, ApiPagination) if defined?(ActionController::API)
33-
34-
if defined?(WillPaginate::CollectionMethods)
35-
WillPaginate::CollectionMethods.module_eval do
36-
def first_page?() !previous_page end
37-
def last_page?() !next_page end
38-
end
39-
end
4+
ApiPagination::Hooks.init

lib/api-pagination/hooks.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
module ApiPagination
2+
class Hooks
3+
def self.init
4+
begin; require 'rails'; rescue LoadError; end
5+
if defined?(ActionController::Base)
6+
require 'rails/pagination'
7+
ActionController::Base.send(:include, Rails::Pagination)
8+
end
9+
10+
begin; require 'rails-api'; rescue LoadError; end
11+
if defined?(ActionController::API)
12+
require 'rails/pagination'
13+
ActionController::API.send(:include, Rails::Pagination)
14+
end
15+
16+
begin; require 'will_paginate'; rescue LoadError; end
17+
if defined?(WillPaginate::CollectionMethod)
18+
WillPaginate::CollectionMethods.module_eval do
19+
def first_page?() !previous_page end
20+
def last_page?() !next_page end
21+
end
22+
end
23+
24+
begin; require 'kaminari'; rescue LoadError; end
25+
26+
STDERR.puts <<-EOC unless defined?(Kaminari) || defined?(WillPaginate)
27+
Warning: api-pagination relies on either Kaminari or WillPaginate. Please
28+
install either dependency by adding one of the following to your Gemfile:
29+
30+
gem 'kaminari'
31+
gem 'will_paginate'
32+
33+
EOC
34+
end
35+
end
36+
end

lib/rails/pagination.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module Rails
2+
module Pagination
3+
protected
4+
5+
def paginate(scope)
6+
links = (headers['Link'] || "").split(',').map(&:strip)
7+
8+
scope = instance_variable_get(:"@#{scope}")
9+
url = request.original_url.sub(/\?.*$/, '')
10+
pages = {}
11+
12+
unless scope.first_page?
13+
pages[:first] = 1
14+
pages[:prev] = scope.current_page - 1
15+
end
16+
17+
unless scope.last_page?
18+
pages[:last] = scope.total_pages
19+
pages[:next] = scope.current_page + 1
20+
end
21+
22+
pages.each do |k, v|
23+
new_params = request.query_parameters.merge(:page => v)
24+
links << %(<#{url}?#{new_params.to_param}>; rel="#{k}")
25+
end
26+
27+
headers['Link'] = links.join(', ') unless links.empty?
28+
29+
return scope
30+
end
31+
end
32+
end

spec/controllers/numbers_controller_spec.rb renamed to spec/rails_spec.rb

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,4 @@
1-
require 'spec_helper'
2-
3-
Rails.application.routes.draw do
4-
resources :numbers, only: [:index]
5-
end
6-
7-
# quacks like Kaminari
8-
PaginatedSet = Struct.new(:current_page, :total_count) do
9-
def limit_value() 25 end
10-
11-
def total_pages
12-
total_count.zero? ? 1 : (total_count.to_f / limit_value).ceil
13-
end
14-
15-
def first_page?() current_page == 1 end
16-
def last_page?() current_page == total_pages end
17-
end
18-
19-
class NumbersController < ActionController::Base
20-
include Rails.application.routes.url_helpers
21-
22-
after_filter only: [:index] { paginate(:numbers) }
23-
24-
def index
25-
page = params.fetch(:page, 1).to_i
26-
total = params.fetch(:count).to_i
27-
28-
if params[:with_headers]
29-
query = request.query_parameters
30-
query.delete(:with_headers)
31-
headers['Link'] = %(<#{numbers_url}?#{query.to_param}>; rel="without") if params[:with_headers]
32-
end
33-
34-
@numbers = PaginatedSet.new(page, total)
35-
render json: @numbers
36-
end
37-
end
1+
require 'rails_spec_helper'
382

393
describe NumbersController, :type => :controller do
404
describe 'GET #index' do

spec/rails_spec_helper.rb

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
require 'action_controller'
2+
require 'spec_helper'
3+
4+
module Rails
5+
def self.application
6+
@application ||= begin
7+
routes = ActionDispatch::Routing::RouteSet.new
8+
OpenStruct.new(routes: routes, env_config: {})
9+
end
10+
end
11+
end
12+
13+
module ControllerExampleGroup
14+
def self.included(base)
15+
base.extend ClassMethods
16+
base.send(:include, ActionController::TestCase::Behavior)
17+
18+
base.prepend_before do
19+
@routes = Rails.application.routes
20+
@controller = described_class.new
21+
end
22+
end
23+
24+
module ClassMethods
25+
def setup(*methods)
26+
methods.each do |method|
27+
if method.to_s =~ /^setup_(fixtures|controller_request_and_response)$/
28+
prepend_before { send method }
29+
else
30+
before { send method }
31+
end
32+
end
33+
end
34+
35+
def teardown(*methods)
36+
methods.each { |method| after { send method } }
37+
end
38+
end
39+
end
40+
41+
Rails.application.routes.draw do
42+
resources :numbers, only: [:index]
43+
end
44+
45+
class NumbersController < ActionController::Base
46+
include Rails.application.routes.url_helpers
47+
48+
after_filter only: [:index] { paginate(:numbers) }
49+
50+
def index
51+
page = params.fetch(:page, 1).to_i
52+
total = params.fetch(:count).to_i
53+
54+
if params[:with_headers]
55+
query = request.query_parameters
56+
query.delete(:with_headers)
57+
headers['Link'] = %(<#{numbers_url}?#{query.to_param}>; rel="without") if params[:with_headers]
58+
end
59+
60+
@numbers = PaginatedSet.new(page, total)
61+
render json: @numbers
62+
end
63+
end
64+
65+
RSpec.configure do |config|
66+
config.include ControllerExampleGroup, :type => :controller
67+
end

spec/spec_helper.rb

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,23 @@
1-
require 'action_controller'
21
require 'api-pagination'
32
require 'rspec/autorun'
43
require 'ostruct'
54

6-
module Rails
7-
def self.application
8-
@application ||= begin
9-
routes = ActionDispatch::Routing::RouteSet.new
10-
OpenStruct.new(routes: routes, env_config: {})
11-
end
12-
end
13-
end
5+
# Quacks like Kaminari
6+
PaginatedSet = Struct.new(:current_page, :total_count) do
7+
def limit_value() 25 end
148

15-
module ControllerExampleGroup
16-
def self.included(base)
17-
base.extend ClassMethods
18-
base.send(:include, ActionController::TestCase::Behavior)
19-
20-
base.prepend_before do
21-
@routes = Rails.application.routes
22-
@controller = described_class.new
23-
end
9+
def total_pages
10+
total_count.zero? ? 1 : (total_count.to_f / limit_value).ceil
2411
end
2512

26-
module ClassMethods
27-
def setup(*methods)
28-
methods.each do |method|
29-
if method.to_s =~ /^setup_(fixtures|controller_request_and_response)$/
30-
prepend_before { send method }
31-
else
32-
before { send method }
33-
end
34-
end
35-
end
36-
37-
def teardown(*methods)
38-
methods.each { |method| after { send method } }
39-
end
40-
end
13+
def first_page?() current_page == 1 end
14+
def last_page?() current_page == total_pages end
4115
end
4216

4317
RSpec.configure do |config|
44-
config.treat_symbols_as_metadata_keys_with_true_values = true
45-
config.run_all_when_everything_filtered = true
46-
config.filter_run :focus
47-
4818
# Run specs in random order to surface order dependencies. If you find an
4919
# order dependency and want to debug it, you can fix the order by providing
5020
# the seed, which is printed after each run.
5121
# --seed 1234
5222
config.order = 'random'
53-
54-
config.include ControllerExampleGroup, :type => :controller
5523
end

0 commit comments

Comments
 (0)