Skip to content

ActiveRecord::Base subclasses that are defined before Kaminari is loaded now get the proper mixins #119

Merged
merged 1 commit into from Aug 21, 2011
View
20 lib/kaminari/models/active_record_extension.rb
@@ -1,24 +1,18 @@
-require File.join(File.dirname(__FILE__), 'active_record_relation_methods')
+require File.join(File.dirname(__FILE__), 'active_record_model_extension')
module Kaminari
module ActiveRecordExtension
extend ActiveSupport::Concern
included do
+ # Future subclasses will pick up the model extension
def self.inherited(kls) #:nodoc:
super
+ kls.send(:include, Kaminari::ActiveRecordModelExtension)
+ end
- kls.class_eval do
- include Kaminari::ConfigurationMethods
-
- # Fetch the values at the specified page number
- # Model.page(5)
- scope :page, Proc.new {|num|
- limit(default_per_page).offset(default_per_page * ([num.to_i, 1].max - 1))
- } do
- include Kaminari::ActiveRecordRelationMethods
- include Kaminari::PageScopeMethods
- end
- end
+ # Existing subclasses pick up the model extension as well
+ self.descendants.each do |kls|
+ kls.send(:include, Kaminari::ActiveRecordModelExtension)
end
end
end
View
20 lib/kaminari/models/active_record_model_extension.rb
@@ -0,0 +1,20 @@
+require File.join(File.dirname(__FILE__), 'active_record_relation_methods')
+
+module Kaminari
+ module ActiveRecordModelExtension
+ extend ActiveSupport::Concern
+
+ included do
+ self.send(:include, Kaminari::ConfigurationMethods)
+
+ # Fetch the values at the specified page number
+ # Model.page(5)
+ self.scope :page, Proc.new {|num|
+ limit(default_per_page).offset(default_per_page * ([num.to_i, 1].max - 1))
+ } do
+ include Kaminari::ActiveRecordRelationMethods
+ include Kaminari::PageScopeMethods
+ end
+ end
+ end
+end
View
1 spec/fake_app.rb
@@ -72,6 +72,7 @@ def index
#migrations
class CreateAllTables < ActiveRecord::Migration
def self.up
+ create_table(:gem_defined_models) { |t| t.string :name; t.integer :age }
create_table(:users) {|t| t.string :name; t.integer :age}
create_table(:books) {|t| t.string :title}
create_table(:readerships) {|t| t.integer :user_id; t.integer :book_id }
View
6 spec/fake_gem.rb
@@ -0,0 +1,6 @@
+# Simulate a gem providing a subclass of ActiveRecord::Base before the Railtie is loaded.
+
+require 'active_record'
+
+class GemDefinedModel < ActiveRecord::Base
+end
View
288 spec/models/scopes_spec.rb
@@ -1,149 +1,153 @@
require File.expand_path('../spec_helper', File.dirname(__FILE__))
-describe Kaminari::ActiveRecordExtension do
- before :all do
- 1.upto(100) {|i| User.create! :name => "user#{'%03d' % i}", :age => (i / 10)}
- end
-
- describe '#page' do
- shared_examples_for 'the first page' do
- it { should have(25).users }
- its('first.name') { should == 'user001' }
- end
-
- shared_examples_for 'blank page' do
- it { should have(0).users }
- end
-
- context 'page 1' do
- subject { User.page 1 }
- it_should_behave_like 'the first page'
- end
-
- context 'page 2' do
- subject { User.page 2 }
- it { should have(25).users }
- its('first.name') { should == 'user026' }
- end
-
- context 'page without an argument' do
- subject { User.page }
- it_should_behave_like 'the first page'
- end
-
- context 'page < 1' do
- subject { User.page 0 }
- it_should_behave_like 'the first page'
- end
-
- context 'page > max page' do
- subject { User.page 5 }
- it_should_behave_like 'blank page'
- end
-
- describe 'ensure #order_values is preserved' do
- subject { User.order('id').page 1 }
- its(:order_values) { should == ['id'] }
- end
- end
-
- describe '#per' do
- context 'page 1 per 5' do
- subject { User.page(1).per(5) }
- it { should have(5).users }
- its('first.name') { should == 'user001' }
- end
- end
-
- describe '#num_pages' do
- context 'per 25 (default)' do
- subject { User.page }
- its(:num_pages) { should == 4 }
- end
-
- context 'per 7' do
- subject { User.page(2).per(7) }
- its(:num_pages) { should == 15 }
- end
-
- context 'per 65536' do
- subject { User.page(50).per(65536) }
- its(:num_pages) { should == 1 }
- end
-
- context 'per 0 (using default)' do
- subject { User.page(50).per(0) }
- its(:num_pages) { should == 4 }
- end
-
- context 'per -1 (using default)' do
- subject { User.page(5).per(-1) }
- its(:num_pages) { should == 4 }
- end
-
- context 'per "String value that can not be converted into Number" (using default)' do
- subject { User.page(5).per('aho') }
- its(:num_pages) { should == 4 }
- end
- end
-
- describe '#current_page' do
- context 'page 1' do
- subject { User.page }
- its(:current_page) { should == 1 }
- end
-
- context 'page 2' do
- subject { User.page(2).per 3 }
- its(:current_page) { should == 2 }
- end
- end
-
- describe '#first_page?' do
- context 'on first page' do
- subject { User.page(1).per(10) }
- its(:first_page?) { should == true }
- end
-
- context 'not on first page' do
- subject { User.page(5).per(10) }
- its(:first_page?) { should == false }
- end
- end
-
- describe '#last_page?' do
- context 'on last page' do
- subject { User.page(10).per(10) }
- its(:last_page?) { should == true }
- end
-
- context 'not on last page' do
- subject { User.page(1).per(10) }
- its(:last_page?) { should == false }
- end
- end
+shared_examples_for 'the first page' do
+ it { should have(25).users }
+ its('first.name') { should == 'user001' }
+end
- describe '#count' do
- context 'page 1' do
- subject { User.page }
- its(:count) { should == 25 }
- end
+shared_examples_for 'blank page' do
+ it { should have(0).users }
+end
- context 'page 2' do
- subject { User.page 2 }
- its(:count) { should == 25 }
+describe Kaminari::ActiveRecordExtension do
+ [User, GemDefinedModel].each do |model_class|
+ context "for #{model_class}" do
+ before :all do
+ 1.upto(100) {|i| model_class.create! :name => "user#{'%03d' % i}", :age => (i / 10)}
+ end
+
+ describe '#page' do
+ context 'page 1' do
+ subject { model_class.page 1 }
+ it_should_behave_like 'the first page'
+ end
+
+ context 'page 2' do
+ subject { model_class.page 2 }
+ it { should have(25).users }
+ its('first.name') { should == 'user026' }
+ end
+
+ context 'page without an argument' do
+ subject { model_class.page }
+ it_should_behave_like 'the first page'
+ end
+
+ context 'page < 1' do
+ subject { model_class.page 0 }
+ it_should_behave_like 'the first page'
+ end
+
+ context 'page > max page' do
+ subject { model_class.page 5 }
+ it_should_behave_like 'blank page'
+ end
+
+ describe 'ensure #order_values is preserved' do
+ subject { model_class.order('id').page 1 }
+ its(:order_values) { should == ['id'] }
+ end
+ end
+
+ describe '#per' do
+ context 'page 1 per 5' do
+ subject { model_class.page(1).per(5) }
+ it { should have(5).users }
+ its('first.name') { should == 'user001' }
+ end
+ end
+
+ describe '#num_pages' do
+ context 'per 25 (default)' do
+ subject { model_class.page }
+ its(:num_pages) { should == 4 }
+ end
+
+ context 'per 7' do
+ subject { model_class.page(2).per(7) }
+ its(:num_pages) { should == 15 }
+ end
+
+ context 'per 65536' do
+ subject { model_class.page(50).per(65536) }
+ its(:num_pages) { should == 1 }
+ end
+
+ context 'per 0 (using default)' do
+ subject { model_class.page(50).per(0) }
+ its(:num_pages) { should == 4 }
+ end
+
+ context 'per -1 (using default)' do
+ subject { model_class.page(5).per(-1) }
+ its(:num_pages) { should == 4 }
+ end
+
+ context 'per "String value that can not be converted into Number" (using default)' do
+ subject { model_class.page(5).per('aho') }
+ its(:num_pages) { should == 4 }
+ end
+ end
+
+ describe '#current_page' do
+ context 'page 1' do
+ subject { model_class.page }
+ its(:current_page) { should == 1 }
+ end
+
+ context 'page 2' do
+ subject { model_class.page(2).per 3 }
+ its(:current_page) { should == 2 }
+ end
+ end
+
+ describe '#first_page?' do
+ context 'on first page' do
+ subject { model_class.page(1).per(10) }
+ its(:first_page?) { should == true }
+ end
+
+ context 'not on first page' do
+ subject { model_class.page(5).per(10) }
+ its(:first_page?) { should == false }
+ end
+ end
+
+ describe '#last_page?' do
+ context 'on last page' do
+ subject { model_class.page(10).per(10) }
+ its(:last_page?) { should == true }
+ end
+
+ context 'not on last page' do
+ subject { model_class.page(1).per(10) }
+ its(:last_page?) { should == false }
+ end
+ end
+
+ describe '#count' do
+ context 'page 1' do
+ subject { model_class.page }
+ its(:count) { should == 25 }
+ end
+
+ context 'page 2' do
+ subject { model_class.page 2 }
+ its(:count) { should == 25 }
+ end
+ end
+
+ context 'chained with .group' do
+ subject { model_class.group('age').page(2).per 5 }
+ # 0..10
+ its(:total_count) { should == 11 }
+ its(:num_pages) { should == 3 }
+ end
+
+ context 'activerecord descendants' do
+ subject { ActiveRecord::Base.descendants }
+ its(:length) { should_not == 0 }
+ end
end
end
-
- context 'chained with .group' do
- subject { User.group('age').page(2).per 5 }
- # 0..10
- its(:total_count) { should == 11 }
- its(:num_pages) { should == 3 }
- end
-
- context 'activerecord descendants' do
- subject { ActiveRecord::Base.descendants }
- its(:length) { should_not == 0 }
- end
end
View
1 spec/spec_helper.rb
@@ -12,6 +12,7 @@
if RUBY_VERSION >= '1.9.2'
YAML::ENGINE.yamler = 'syck'
end
+require File.join(File.dirname(__FILE__), 'fake_gem')
require File.join(File.dirname(__FILE__), 'fake_app')
require 'rspec/rails'
Something went wrong with that request. Please try again.