Merge branch 'datamapper-int' of https://github.com/Ragmaanir/kaminari 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
This commit is contained in:
Akira Matsuda 2011-08-29 20:23:13 +09:00
commit 3236398bc7
6 changed files with 177 additions and 55 deletions

View File

@ -27,6 +27,8 @@ Gem::Specification.new do |s|
s.add_development_dependency 'mongoid', ['>= 2']
s.add_development_dependency 'mongo_mapper', ['>= 0.9']
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 'rspec', ['>= 0']
s.add_development_dependency 'rspec-rails', ['>= 0']

View File

@ -11,13 +11,8 @@ module Kaminari
end
def total_count #:nodoc:
return count if query.options.blank?
opts = query.options.dup
opts.delete(:limit)
opts.delete(:offset)
opts.delete(:order)
model.all(opts).count
model.count(query.options.except(:limit, :offset, :order))
end
end
end
end
end

View File

@ -2,41 +2,44 @@ require 'kaminari/models/data_mapper_collection_methods'
module Kaminari
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
extend ActiveSupport::Concern
included do
include Kaminari::ConfigurationMethods::ClassMethods
include Kaminari::DataMapperCollectionMethods
include Kaminari::PageScopeMethods
# 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
include Paginatable
end
end
module Model
extend ActiveSupport::Concern
included do
# Fetch the values at the specified page number
# Model.page(5)
def page(*args)
all.page(*args)
end
include Kaminari::ConfigurationMethods::ClassMethods
include Paginatable
def per(*args)
all.per(*args)
end
def limit(val)
all(:limit => val)
end
def limit(val)
all(:limit => val)
end
def offset(val)
all(:offset => val)
end
def offset(val)
all(:offset => val)
end
end
end

View File

@ -2,7 +2,7 @@ require 'rails'
# ensure ORMs are loaded *before* initializing Kaminari
begin; require 'mongoid'; 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/helpers/action_view_extension'
@ -17,6 +17,7 @@ module Kaminari
require 'kaminari/models/active_record_extension'
::ActiveRecord::Base.send :include, Kaminari::ActiveRecordExtension
end
if defined? ::Mongoid
require 'kaminari/models/mongoid_extension'
::Mongoid::Document.send :include, Kaminari::MongoidExtension::Document
@ -32,11 +33,14 @@ module Kaminari
if defined? ::DataMapper
require 'kaminari/models/data_mapper_extension'
::DataMapper::Model.send :include, Kaminari::DataMapperExtension::Model
::DataMapper::Collection.send :include, Kaminari::DataMapperExtension::Collection
::DataMapper::Model.append_extensions Kaminari::DataMapperExtension::Model
# ::DataMapper::Model.send :extend, Kaminari::DataMapperExtension::Model
end
require 'kaminari/models/array_extension'
require File.join(File.dirname(__FILE__), 'models/array_extension')
ActiveSupport.on_load(:action_view) do
::ActionView::Base.send :include, Kaminari::ActionViewExtension
end

View File

@ -1,64 +1,181 @@
require File.expand_path('../spec_helper', File.dirname(__FILE__))
require 'dm-core'
require 'dm-migrations'
require 'dm-aggregates'
require 'kaminari/models/data_mapper_extension'
describe Kaminari::DataMapperExtension do
before :all do
DataMapper.setup(:default, 'sqlite::memory:')
class Developer
class Worker
include ::DataMapper::Resource
property :id, Serial
property :salary, Integer
property :name, String, :required => true
property :age, Integer, :required => true
has n, :projects, :through => Resource
end
class Project
include ::DataMapper::Resource
property :id, Serial
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
worker0 = Worker[0]
50.times do |i|
worker0.projects << Project.create(:name => "Project#{i}")
end
worker0.projects.save
end
before do
stub(subject).count { 300 } # in order to avoid DB access...
describe 'Collection' do
subject{ Worker.all }
it { should respond_to(:page) }
it { should_not respond_to(:per) }
end
describe 'Model' do
subject{ Worker }
it { should respond_to(:page) }
it { should respond_to(:default_per_page) }
it { should_not respond_to(:per) }
end
describe '#page' do
context 'page 1' do
subject { Developer.page(1) }
context 'page 0' do
subject { Worker.all(:age.gte => 200).page 0 }
it { should be_a DataMapper::Collection }
its(:current_page) { should == 1 }
its(:limit_value) { should == 25 }
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
subject { Worker.all(:age.gte => 0).page 1 }
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 == 300 }
its(:num_pages) { should == 12 }
it { should offset(0) }
end
context 'page 2' do
subject { Developer.page 2 }
subject { Worker.page 2 }
it { should be_a DataMapper::Collection }
its(:current_page) { should == 2 }
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 }
it { should offset 25 }
end
context 'page "foobar"' do
subject { Developer.page 'foobar' }
subject { Worker.page 'foobar' }
it { should be_a DataMapper::Collection }
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 }
it { should offset 0 }
end
context 'page 1 with another conditions' do
subject { Developer.page(2) }
context 'with criteria before' do
subject { Worker.all(:age.gt => 100).page 2 }
it { should be_a DataMapper::Collection }
its(:current_page) { should == 2 }
its(:limit_value) { should == 25 }
its(:num_pages) { should == 12 }
it { should offset(25) }
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
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
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 }
its(:current_page) { should == 2 }
its(:current_page) { should == 2 }
its('query.limit') { should == 10 }
its(:limit_value) { should == 10 }
its(:num_pages) { should == 30 }
it { should offset 10 }
its('query.offset') { should == 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

View File

@ -2,6 +2,7 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'rails'
require 'mongoid'
require 'dm-core'
require 'kaminari'
require 'database_cleaner'
# Ensure we use 'syck' instead of 'psych' in 1.9.2