Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

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

Merged
merged 1 commit into from

4 participants

Pivotal Casebook J. Pablo Fernández 2-718 Akira Matsuda
Pivotal Casebook

We have a gem that provides an ActiveRecord::Base subclass. However, since it is loaded by Bundler before the self.included hook is mixed into to ActiveRecord::Base, it never gets the "page" scope.

With our fix, mixing in the module will back-fill existing subclasses with the scope.

Grant Hutchins & Sam Obukwelu Active Record models that were subclassed before Kaminari::ActiveReco…
…rdExtension is included pick up the extensions.
6998b5f
J. Pablo Fernández

I also had the problem of not having pagination of these model, in my case it was the Audit model. I switched to Casecommons's repo and it worked :)

2-718

I'm using the acts_as_audited gem v2.0.0.rc7 and the Audit class would not paginate until I switched to Casecommon's kaminari v0.12.4 repo. This works for me now.

Akira Matsuda amatsuda merged commit 6998b5f into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 20, 2011
  1. Active Record models that were subclassed before Kaminari::ActiveReco…

    Grant Hutchins & Sam Obukwelu authored
    …rdExtension is included pick up the extensions.
This page is out of date. Refresh to see the latest.
20 lib/kaminari/models/active_record_extension.rb
View
@@ -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
20 lib/kaminari/models/active_record_model_extension.rb
View
@@ -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
1  spec/fake_app.rb
View
@@ -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 }
6 spec/fake_gem.rb
View
@@ -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
288 spec/models/scopes_spec.rb
View
@@ -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
1  spec/spec_helper.rb
View
@@ -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.