Skip to content

Commit

Permalink
Merge branch 'datamapper-int' of https://github.com/Ragmaanir/kaminari
Browse files Browse the repository at this point in the history
…into Ragmaanir-datamapper-int

Conflicts:
	kaminari.gemspec
	lib/kaminari/models/data_mapper_extension.rb
	lib/kaminari/railtie.rb
	spec/models/data_mapper_spec.rb

also, refactored a lot to make the code simple
  • Loading branch information
amatsuda committed Aug 29, 2011
2 parents 27160db + 21ceb9f commit 3236398
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 56 deletions.
2 changes: 2 additions & 0 deletions kaminari.gemspec
Expand Up @@ -27,6 +27,8 @@ Gem::Specification.new do |s|
s.add_development_dependency 'mongoid', ['>= 2'] s.add_development_dependency 'mongoid', ['>= 2']
s.add_development_dependency 'mongo_mapper', ['>= 0.9'] s.add_development_dependency 'mongo_mapper', ['>= 0.9']
s.add_development_dependency 'dm-core', ['>= 1.1.0'] s.add_development_dependency 'dm-core', ['>= 1.1.0']
s.add_development_dependency 'dm-migrations', ['>= 1.1.0']
s.add_development_dependency 'dm-aggregates', ['>= 1.1.0']
s.add_development_dependency 'dm-sqlite-adapter', ['>= 1.1.0'] s.add_development_dependency 'dm-sqlite-adapter', ['>= 1.1.0']
s.add_development_dependency 'rspec', ['>= 0'] s.add_development_dependency 'rspec', ['>= 0']
s.add_development_dependency 'rspec-rails', ['>= 0'] s.add_development_dependency 'rspec-rails', ['>= 0']
Expand Down
9 changes: 2 additions & 7 deletions lib/kaminari/models/data_mapper_collection_methods.rb
Expand Up @@ -11,13 +11,8 @@ def offset_value #:nodoc:
end end


def total_count #:nodoc: def total_count #:nodoc:
return count if query.options.blank? model.count(query.options.except(:limit, :offset, :order))
opts = query.options.dup
opts.delete(:limit)
opts.delete(:offset)
opts.delete(:order)
model.all(opts).count
end end
end end
end end
end end
55 changes: 29 additions & 26 deletions lib/kaminari/models/data_mapper_extension.rb
Expand Up @@ -2,41 +2,44 @@


module Kaminari module Kaminari
module DataMapperExtension module DataMapperExtension
module Paginatable
def page(num)
num = [num.to_i, 1].max - 1
all(:limit => default_per_page, :offset => default_per_page * num).extend Paginating
end
end

module Paginating
include Kaminari::PageScopeMethods

def all(options={})
super.extend Paginating
end

def per(num)
super.extend Paginating
end
end

module Collection module Collection
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
include Kaminari::ConfigurationMethods::ClassMethods include Kaminari::ConfigurationMethods::ClassMethods
include Kaminari::DataMapperCollectionMethods include Kaminari::DataMapperCollectionMethods
include Kaminari::PageScopeMethods include Paginatable

# Fetch the values at the specified page number
# Model.all(:some => :conditions).page(5)
def page(num)
limit(default_per_page).offset(default_per_page * ([num.to_i, 1].max - 1))
end
end end
end end


module Model module Model
extend ActiveSupport::Concern include Kaminari::ConfigurationMethods::ClassMethods
included do include Paginatable
# Fetch the values at the specified page number
# Model.page(5) def limit(val)
def page(*args) all(:limit => val)
all.page(*args) end
end

def offset(val)
def per(*args) all(:offset => val)
all.per(*args)
end

def limit(val)
all(:limit => val)
end

def offset(val)
all(:offset => val)
end
end end
end end
end end
Expand Down
8 changes: 6 additions & 2 deletions lib/kaminari/railtie.rb
Expand Up @@ -2,7 +2,7 @@
# ensure ORMs are loaded *before* initializing Kaminari # ensure ORMs are loaded *before* initializing Kaminari
begin; require 'mongoid'; rescue LoadError; end begin; require 'mongoid'; rescue LoadError; end
begin; require 'mongo_mapper'; rescue LoadError; end begin; require 'mongo_mapper'; rescue LoadError; end
begin; require 'dm-core'; rescue LoadError; end begin; require 'dm-core'; require 'dm-aggregates'; rescue LoadError; end


require 'kaminari/config' require 'kaminari/config'
require 'kaminari/helpers/action_view_extension' require 'kaminari/helpers/action_view_extension'
Expand All @@ -17,6 +17,7 @@ class Railtie < ::Rails::Railtie #:nodoc:
require 'kaminari/models/active_record_extension' require 'kaminari/models/active_record_extension'
::ActiveRecord::Base.send :include, Kaminari::ActiveRecordExtension ::ActiveRecord::Base.send :include, Kaminari::ActiveRecordExtension
end end

if defined? ::Mongoid if defined? ::Mongoid
require 'kaminari/models/mongoid_extension' require 'kaminari/models/mongoid_extension'
::Mongoid::Document.send :include, Kaminari::MongoidExtension::Document ::Mongoid::Document.send :include, Kaminari::MongoidExtension::Document
Expand All @@ -32,11 +33,14 @@ class Railtie < ::Rails::Railtie #:nodoc:


if defined? ::DataMapper if defined? ::DataMapper
require 'kaminari/models/data_mapper_extension' require 'kaminari/models/data_mapper_extension'
::DataMapper::Model.send :include, Kaminari::DataMapperExtension::Model
::DataMapper::Collection.send :include, Kaminari::DataMapperExtension::Collection ::DataMapper::Collection.send :include, Kaminari::DataMapperExtension::Collection
::DataMapper::Model.append_extensions Kaminari::DataMapperExtension::Model
# ::DataMapper::Model.send :extend, Kaminari::DataMapperExtension::Model
end end
require 'kaminari/models/array_extension' require 'kaminari/models/array_extension'


require File.join(File.dirname(__FILE__), 'models/array_extension')

ActiveSupport.on_load(:action_view) do ActiveSupport.on_load(:action_view) do
::ActionView::Base.send :include, Kaminari::ActionViewExtension ::ActionView::Base.send :include, Kaminari::ActionViewExtension
end end
Expand Down
159 changes: 138 additions & 21 deletions spec/models/data_mapper_spec.rb
@@ -1,64 +1,181 @@
require File.expand_path('../spec_helper', File.dirname(__FILE__)) require File.expand_path('../spec_helper', File.dirname(__FILE__))
require 'dm-core' require 'dm-core'
require 'dm-migrations'
require 'dm-aggregates'
require 'kaminari/models/data_mapper_extension' require 'kaminari/models/data_mapper_extension'


describe Kaminari::DataMapperExtension do describe Kaminari::DataMapperExtension do
before :all do before :all do
DataMapper.setup(:default, 'sqlite::memory:') DataMapper.setup(:default, 'sqlite::memory:')
class Developer
class Worker
include ::DataMapper::Resource

property :id, Serial
property :name, String, :required => true
property :age, Integer, :required => true

has n, :projects, :through => Resource
end

class Project
include ::DataMapper::Resource include ::DataMapper::Resource

property :id, Serial property :id, Serial
property :salary, Integer property :name, String, :required => true

has n, :workers, :through => Resource
end

DataMapper.finalize
DataMapper.auto_migrate!

300.times do |i|
Worker.create(:name => "Worker#{i}", :age => i)
end end

worker0 = Worker[0]
50.times do |i|
worker0.projects << Project.create(:name => "Project#{i}")
end
worker0.projects.save
end

describe 'Collection' do
subject{ Worker.all }
it { should respond_to(:page) }
it { should_not respond_to(:per) }
end end
before do
stub(subject).count { 300 } # in order to avoid DB access... describe 'Model' do
subject{ Worker }
it { should respond_to(:page) }
it { should respond_to(:default_per_page) }
it { should_not respond_to(:per) }
end end


describe '#page' do describe '#page' do
context 'page 0' do
subject { Worker.all(:age.gte => 200).page 0 }
it { should be_a DataMapper::Collection }
its(:current_page) { should == 1 }
its('query.limit') { should == 25 }
its('query.offset') { should == 0 }
its(:total_count) { should == Worker.count(:age.gte => 200) }
its(:num_pages) { should == 4 }
end

context 'page 1' do context 'page 1' do
subject { Developer.page(1) } subject { Worker.all(:age.gte => 0).page 1 }
it { should be_a DataMapper::Collection } it { should be_a DataMapper::Collection }
its(:current_page) { should == 1 } its(:current_page) { should == 1 }
its(:limit_value) { should == 25 } its('query.limit') { should == 25 }
its('query.offset') { should == 0 }
its(:total_count) { should == 300 }
its(:num_pages) { should == 12 } its(:num_pages) { should == 12 }
it { should offset(0) }
end end


context 'page 2' do context 'page 2' do
subject { Developer.page 2 } subject { Worker.page 2 }
it { should be_a DataMapper::Collection } it { should be_a DataMapper::Collection }
its(:current_page) { should == 2 } its(:current_page) { should == 2 }
its(:limit_value) { should == 25 } its(:limit_value) { should == 25 }
its('query.limit') { should == 25 }
its('query.offset') { should == 25 }
its(:total_count) { should == 300 }
its(:num_pages) { should == 12 } its(:num_pages) { should == 12 }
it { should offset 25 }
end end


context 'page "foobar"' do context 'page "foobar"' do
subject { Developer.page 'foobar' } subject { Worker.page 'foobar' }
it { should be_a DataMapper::Collection } it { should be_a DataMapper::Collection }
its(:current_page) { should == 1 } its(:current_page) { should == 1 }
its(:limit_value) { should == 25 } its('query.limit') { should == 25 }
its('query.offset') { should == 0 }
its(:total_count) { should == 300 }
its(:num_pages) { should == 12 } its(:num_pages) { should == 12 }
it { should offset 0 }
end end


context 'page 1 with another conditions' do context 'with criteria before' do
subject { Developer.page(2) } subject { Worker.all(:age.gt => 100).page 2 }
it { should be_a DataMapper::Collection } it { should be_a DataMapper::Collection }
its(:current_page) { should == 2 } its(:current_page) { should == 2 }
its(:limit_value) { should == 25 } its('query.limit') { should == 25 }
its(:num_pages) { should == 12 } its('query.offset') { should == 25 }
it { should offset(25) } its(:total_count) { should == Worker.count(:age.gt => 100) }
its(:num_pages) { should == 8 }
end

context 'with criteria after' do
subject { Worker.page(2).all(:age.gt => 100) }
it { should be_a DataMapper::Collection }
its(:current_page) { should == 2 }
its('query.limit') { should == 25 }
its('query.offset') { should == 25 }
its(:total_count) { should == Worker.count(:age.gt => 100) }
its(:num_pages) { should == 8 }
end end
end end


describe '#per' do describe '#per' do
subject { Developer.page(2).per(10) } context 'on simple query' do
subject { Worker.page(2).per(10) }
it { should be_a DataMapper::Collection } it { should be_a DataMapper::Collection }
its(:current_page) { should == 2 } its(:current_page) { should == 2 }
its('query.limit') { should == 10 }
its(:limit_value) { should == 10 } its(:limit_value) { should == 10 }
its(:num_pages) { should == 30 } its('query.offset') { should == 10 }
it { should offset 10 } its(:total_count) { should == 300 }
its(:num_pages) { should == 30 }
end

context 'on query with condition' do
subject { Worker.page(5).all(:age.lte => 100).per(13) }
its(:current_page) { should == 5 }
its('query.limit') { should == 13 }
its('query.offset') { should == 52 }
its(:total_count) { should == 101 }
its(:num_pages) { should == 8 }
end

context 'on query with order' do
subject { Worker.page(5).all(:age.lte => 100, :order => [:age.asc]).per(13) }
it('includes worker with age 52') { should include(Worker.first(:age => 52)) }
it('does not include worker with age 51') { should_not include(Worker.first(:age => 51)) }
it('includes worker with age 52') { should include(Worker.first(:age => 64)) }
it('does not include worker with age 51') { should_not include(Worker.first(:age => 65)) }
its(:current_page) { should == 5 }
its('query.limit') { should == 13 }
its('query.offset') { should == 52 }
its(:total_count) { should == 101 }
its(:num_pages) { should == 8 }
end

context 'on chained queries' do
subject { Worker.all(:age.gte => 50).page(3).all(:age.lte => 100).per(13) }
its(:current_page) { should == 3 }
its('query.limit') { should == 13 }
its('query.offset') { should == 26 }
its(:total_count) { should == 51 }
its(:num_pages) { should == 4 }
end

context 'on query on association' do
subject { Worker[0].projects.page(3).all(:name.like => 'Project%').per(5) }
its(:current_page) { should == 3 }
its('query.limit') { should == 5 }
its('query.offset') { should == 10 }
its(:total_count) { should == 50 }
its(:num_pages) { should == 10 }
end

context 'on query with association conditions' do
subject { Worker.page(3).all(:projects => Project.all).per(5) }
its(:current_page) { should == 3 }
its('query.limit') { should == 5 }
its('query.offset') { should == 10 }
its(:total_count) { should == 50 }
its(:num_pages) { should == 10 }
end
end end
end end
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Expand Up @@ -2,6 +2,7 @@
$LOAD_PATH.unshift(File.dirname(__FILE__)) $LOAD_PATH.unshift(File.dirname(__FILE__))
require 'rails' require 'rails'
require 'mongoid' require 'mongoid'
require 'dm-core'
require 'kaminari' require 'kaminari'
require 'database_cleaner' require 'database_cleaner'
# Ensure we use 'syck' instead of 'psych' in 1.9.2 # Ensure we use 'syck' instead of 'psych' in 1.9.2
Expand Down

0 comments on commit 3236398

Please sign in to comment.