Skip to content

Commit c9578ad

Browse files
authored
Merge pull request #95 from mach-kernel/fix-detect-model
Better behavior for #detect_model
2 parents 8b75996 + 3b6ae63 commit c9578ad

File tree

6 files changed

+91
-11
lines changed

6 files changed

+91
-11
lines changed

api-pagination.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ Gem::Specification.new do |s|
2121
s.add_development_dependency 'railties', '>= 5.0.0'
2222
s.add_development_dependency 'actionpack', '>= 5.0.0'
2323
s.add_development_dependency 'sequel', '>= 4.9.0'
24+
s.add_development_dependency 'activerecord-nulldb-adapter', '>= 0.3.9'
2425
end

lib/api-pagination.rb

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,24 +118,23 @@ def paginate_with_will_paginate(collection, options)
118118

119119
def get_default_per_page_for_kaminari(collection)
120120
default = Kaminari.config.default_per_page
121-
detect_model(collection).default_per_page || default
122-
rescue
123-
default
121+
extract_per_page_from_model(collection, :default_per_page) || default
124122
end
125123

126124
def default_per_page_for_will_paginate(collection)
127125
default = WillPaginate.per_page
128-
detect_model(collection).per_page || default
129-
rescue
130-
default
126+
extract_per_page_from_model(collection, :per_page) || default
131127
end
132128

133-
def detect_model(collection)
134-
if collection.respond_to?(:table_name)
135-
collection.table_name.classify.constantize
129+
def extract_per_page_from_model(collection, accessor)
130+
klass = if collection.respond_to?(:klass)
131+
collection.klass
136132
else
137133
collection.first.class
138134
end
135+
136+
return unless klass.respond_to?(accessor)
137+
klass.send(accessor)
139138
end
140139
end
141140
end

spec/active_record_spec.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
require 'spec_helper'
2+
require 'support/active_record/foo'
3+
require 'nulldb_rspec'
4+
5+
ActiveRecord::Base.establish_connection(
6+
adapter: :nulldb,
7+
schema: 'spec/support/active_record/schema.rb'
8+
)
9+
10+
NullDB.configure { |ndb| def ndb.project_root; Dir.pwd; end; }
11+
12+
shared_examples 'produces_correct_sql' do
13+
it 'produces correct sql for first page' do
14+
allow(collection).to receive(:count).and_return(collection_size)
15+
paginated_sql, _ = ApiPagination.paginate(collection, per_page: per_page)
16+
expect(paginated_sql.to_sql).to eql(Foo.limit(per_page).offset(0).to_sql)
17+
end
18+
end
19+
20+
describe 'ActiveRecord Support' do
21+
let(:collection) { Foo.all }
22+
let(:collection_size) { 50 }
23+
let(:per_page) { 5 }
24+
25+
if ApiPagination.config.paginator == :will_paginate
26+
require 'will_paginate/active_record'
27+
end
28+
29+
context "pagination with #{ApiPagination.config.paginator}" do
30+
include_examples 'produces_correct_sql'
31+
end
32+
33+
34+
if ApiPagination.config.paginator != :pagy
35+
context 'reflections' do
36+
it 'invokes the correct methods to determine type' do
37+
expect(collection).to receive(:klass).at_least(:once)
38+
.and_call_original
39+
ApiPagination.paginate(collection)
40+
end
41+
42+
it 'does not fail if table name is not snake cased class name' do
43+
allow(collection).to receive(:table_name).and_return(SecureRandom.uuid)
44+
expect { ApiPagination.paginate(collection) }.to_not raise_error
45+
end
46+
end
47+
end
48+
end
49+
50+

spec/rails_spec.rb

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,13 +262,21 @@ class Fixnum
262262
end
263263
end
264264

265+
after :all do
266+
class Fixnum
267+
class << self
268+
undef_method :default_per_page, :per_page
269+
end
270+
end
271+
end
272+
265273
it 'should use default per page from model' do
266274
get :index_with_no_per_page, params: {count: 100}
267275

268276
expect(response.header['Per-Page']).to eq('6')
269277
end
270278

271-
it 'should not fail if model does not respond to per page' do
279+
it 'should not fail if the model yields nil for per page' do
272280
class Fixnum
273281
@default_per_page = nil
274282
@per_page = nil
@@ -286,5 +294,19 @@ class Fixnum
286294
end
287295
end
288296
end
297+
298+
context 'default per page in objects without paginator defaults' do
299+
it 'should not fail if model does not respond to per page' do
300+
get :index_with_no_per_page, params: {count: 100}
301+
302+
expect(response.header['Per-Page']).to eq(
303+
case ApiPagination.config.paginator
304+
when :pagy then Pagy::VARS[:items].to_s
305+
when :kaminari then Kaminari.config.default_per_page.to_s
306+
when :will_paginate then WillPaginate.per_page.to_s
307+
end
308+
)
309+
end
310+
end
289311
end
290-
end
312+
end

spec/support/active_record/foo.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
require 'active_record'
2+
3+
class Foo < ActiveRecord::Base; end

spec/support/active_record/schema.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ActiveRecord::Schema.define(version: 0) do
2+
create_table "foos", :force => true do |t|
3+
t.string "foo"
4+
end
5+
end

0 commit comments

Comments
 (0)