cehoffman-acts_as_ferret 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README +68 -0
- data/bin/aaf_install +23 -0
- data/config/ferret_server.yml +24 -0
- data/doc/README.win32 +23 -0
- data/doc/demo/README +154 -0
- data/doc/demo/README_DEMO +23 -0
- data/doc/demo/Rakefile +10 -0
- data/doc/demo/app/controllers/admin/backend_controller.rb +14 -0
- data/doc/demo/app/controllers/admin_area_controller.rb +4 -0
- data/doc/demo/app/controllers/application.rb +5 -0
- data/doc/demo/app/controllers/contents_controller.rb +49 -0
- data/doc/demo/app/controllers/searches_controller.rb +8 -0
- data/doc/demo/app/helpers/admin/backend_helper.rb +2 -0
- data/doc/demo/app/helpers/application_helper.rb +3 -0
- data/doc/demo/app/helpers/content_helper.rb +2 -0
- data/doc/demo/app/helpers/search_helper.rb +2 -0
- data/doc/demo/app/models/comment.rb +48 -0
- data/doc/demo/app/models/content.rb +12 -0
- data/doc/demo/app/models/content_base.rb +28 -0
- data/doc/demo/app/models/search.rb +19 -0
- data/doc/demo/app/models/shared_index1.rb +3 -0
- data/doc/demo/app/models/shared_index2.rb +3 -0
- data/doc/demo/app/models/special_content.rb +3 -0
- data/doc/demo/app/models/stats.rb +20 -0
- data/doc/demo/app/views/admin/backend/search.rhtml +18 -0
- data/doc/demo/app/views/contents/_form.rhtml +10 -0
- data/doc/demo/app/views/contents/edit.rhtml +9 -0
- data/doc/demo/app/views/contents/index.rhtml +24 -0
- data/doc/demo/app/views/contents/new.rhtml +8 -0
- data/doc/demo/app/views/contents/show.rhtml +8 -0
- data/doc/demo/app/views/layouts/application.html.erb +17 -0
- data/doc/demo/app/views/searches/_content.html.erb +2 -0
- data/doc/demo/app/views/searches/search.html.erb +20 -0
- data/doc/demo/config/boot.rb +109 -0
- data/doc/demo/config/database.yml +38 -0
- data/doc/demo/config/environment.rb +69 -0
- data/doc/demo/config/environments/development.rb +16 -0
- data/doc/demo/config/environments/production.rb +19 -0
- data/doc/demo/config/environments/test.rb +21 -0
- data/doc/demo/config/ferret_server.yml +18 -0
- data/doc/demo/config/lighttpd.conf +40 -0
- data/doc/demo/config/routes.rb +9 -0
- data/doc/demo/db/development_structure.sql +15 -0
- data/doc/demo/db/migrate/001_initial_migration.rb +18 -0
- data/doc/demo/db/migrate/002_add_type_to_contents.rb +9 -0
- data/doc/demo/db/migrate/003_create_shared_index1s.rb +11 -0
- data/doc/demo/db/migrate/004_create_shared_index2s.rb +11 -0
- data/doc/demo/db/migrate/005_special_field.rb +9 -0
- data/doc/demo/db/migrate/006_create_stats.rb +15 -0
- data/doc/demo/db/schema.sql +18 -0
- data/doc/demo/doc/README_FOR_APP +2 -0
- data/doc/demo/doc/howto.txt +70 -0
- data/doc/demo/public/.htaccess +40 -0
- data/doc/demo/public/404.html +8 -0
- data/doc/demo/public/500.html +8 -0
- data/doc/demo/public/dispatch.cgi +10 -0
- data/doc/demo/public/dispatch.fcgi +24 -0
- data/doc/demo/public/dispatch.rb +10 -0
- data/doc/demo/public/favicon.ico +0 -0
- data/doc/demo/public/images/rails.png +0 -0
- data/doc/demo/public/index.html +277 -0
- data/doc/demo/public/robots.txt +1 -0
- data/doc/demo/public/stylesheets/scaffold.css +74 -0
- data/doc/demo/script/about +3 -0
- data/doc/demo/script/breakpointer +3 -0
- data/doc/demo/script/console +3 -0
- data/doc/demo/script/destroy +3 -0
- data/doc/demo/script/ferret_server +10 -0
- data/doc/demo/script/generate +3 -0
- data/doc/demo/script/performance/benchmarker +3 -0
- data/doc/demo/script/performance/profiler +3 -0
- data/doc/demo/script/plugin +3 -0
- data/doc/demo/script/process/inspector +3 -0
- data/doc/demo/script/process/reaper +3 -0
- data/doc/demo/script/process/spawner +3 -0
- data/doc/demo/script/process/spinner +3 -0
- data/doc/demo/script/runner +3 -0
- data/doc/demo/script/server +3 -0
- data/doc/demo/test/fixtures/comments.yml +12 -0
- data/doc/demo/test/fixtures/contents.yml +13 -0
- data/doc/demo/test/fixtures/remote_contents.yml +9 -0
- data/doc/demo/test/fixtures/shared_index1s.yml +7 -0
- data/doc/demo/test/fixtures/shared_index2s.yml +7 -0
- data/doc/demo/test/functional/admin/backend_controller_test.rb +35 -0
- data/doc/demo/test/functional/contents_controller_test.rb +81 -0
- data/doc/demo/test/functional/searches_controller_test.rb +71 -0
- data/doc/demo/test/smoke/drb_smoke_test.rb +321 -0
- data/doc/demo/test/smoke/process_stats.rb +21 -0
- data/doc/demo/test/test_helper.rb +30 -0
- data/doc/demo/test/unit/comment_test.rb +217 -0
- data/doc/demo/test/unit/content_test.rb +705 -0
- data/doc/demo/test/unit/ferret_result_test.rb +24 -0
- data/doc/demo/test/unit/multi_index_test.rb +329 -0
- data/doc/demo/test/unit/remote_index_test.rb +23 -0
- data/doc/demo/test/unit/shared_index1_test.rb +108 -0
- data/doc/demo/test/unit/shared_index2_test.rb +13 -0
- data/doc/demo/test/unit/sort_test.rb +21 -0
- data/doc/demo/test/unit/special_content_test.rb +25 -0
- data/doc/demo/vendor/plugins/will_paginate/LICENSE +18 -0
- data/doc/demo/vendor/plugins/will_paginate/README +108 -0
- data/doc/demo/vendor/plugins/will_paginate/Rakefile +23 -0
- data/doc/demo/vendor/plugins/will_paginate/init.rb +21 -0
- data/doc/demo/vendor/plugins/will_paginate/lib/will_paginate/collection.rb +45 -0
- data/doc/demo/vendor/plugins/will_paginate/lib/will_paginate/core_ext.rb +44 -0
- data/doc/demo/vendor/plugins/will_paginate/lib/will_paginate/finder.rb +159 -0
- data/doc/demo/vendor/plugins/will_paginate/lib/will_paginate/view_helpers.rb +95 -0
- data/doc/demo/vendor/plugins/will_paginate/test/array_pagination_test.rb +23 -0
- data/doc/demo/vendor/plugins/will_paginate/test/boot.rb +27 -0
- data/doc/demo/vendor/plugins/will_paginate/test/console +10 -0
- data/doc/demo/vendor/plugins/will_paginate/test/finder_test.rb +219 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/admin.rb +3 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/companies.yml +24 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/company.rb +23 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/developer.rb +11 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/developers_projects.yml +13 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/project.rb +4 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/projects.yml +7 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/replies.yml +20 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/reply.rb +5 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/schema.sql +44 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/topic.rb +19 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/topics.yml +30 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/user.rb +2 -0
- data/doc/demo/vendor/plugins/will_paginate/test/fixtures/users.yml +35 -0
- data/doc/demo/vendor/plugins/will_paginate/test/helper.rb +42 -0
- data/doc/demo/vendor/plugins/will_paginate/test/lib/activerecord_test_connector.rb +64 -0
- data/doc/demo/vendor/plugins/will_paginate/test/lib/load_fixtures.rb +10 -0
- data/doc/demo/vendor/plugins/will_paginate/test/pagination_test.rb +136 -0
- data/doc/monit-example +22 -0
- data/init.rb +24 -0
- data/install.rb +18 -0
- data/lib/act_methods.rb +147 -0
- data/lib/acts_as_ferret.rb +584 -0
- data/lib/ar_mysql_auto_reconnect_patch.rb +41 -0
- data/lib/blank_slate.rb +53 -0
- data/lib/bulk_indexer.rb +38 -0
- data/lib/class_methods.rb +270 -0
- data/lib/ferret_extensions.rb +188 -0
- data/lib/ferret_find_methods.rb +141 -0
- data/lib/ferret_result.rb +53 -0
- data/lib/ferret_server.rb +238 -0
- data/lib/index.rb +99 -0
- data/lib/instance_methods.rb +171 -0
- data/lib/local_index.rb +205 -0
- data/lib/more_like_this.rb +217 -0
- data/lib/multi_index.rb +126 -0
- data/lib/rdig_adapter.rb +148 -0
- data/lib/remote_functions.rb +23 -0
- data/lib/remote_index.rb +54 -0
- data/lib/remote_multi_index.rb +20 -0
- data/lib/search_results.rb +50 -0
- data/lib/server_manager.rb +58 -0
- data/lib/unix_daemon.rb +64 -0
- data/lib/without_ar.rb +52 -0
- data/rakefile +141 -0
- data/recipes/aaf_recipes.rb +114 -0
- data/script/ferret_daemon +94 -0
- data/script/ferret_server +10 -0
- data/script/ferret_service +178 -0
- data/tasks/ferret.rake +22 -0
- metadata +258 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
module WillPaginate
|
|
2
|
+
# = Global options for pagination helpers
|
|
3
|
+
#
|
|
4
|
+
# Options for pagination helpers are optional and get their default values from the
|
|
5
|
+
# WillPaginate::ViewHelpers.pagination_options hash. You can write to this hash to
|
|
6
|
+
# override default options on the global level:
|
|
7
|
+
#
|
|
8
|
+
# WillPaginate::ViewHelpers.pagination_options[:prev_label] = 'Previous page'
|
|
9
|
+
#
|
|
10
|
+
# By putting this into your environment.rb you can easily localize link texts to previous
|
|
11
|
+
# and next pages, as well as override some other defaults to your liking.
|
|
12
|
+
module ViewHelpers
|
|
13
|
+
# default options that can be overriden on the global level
|
|
14
|
+
@@pagination_options = { :class => 'pagination',
|
|
15
|
+
:prev_label => '« Previous',
|
|
16
|
+
:next_label => 'Next »',
|
|
17
|
+
:inner_window => 4, # links around the current page
|
|
18
|
+
:outer_window => 1, # links around beginning and end
|
|
19
|
+
:separator => ' ', # single space is friendly to spiders and non-graphic browsers
|
|
20
|
+
:param_name => :page
|
|
21
|
+
}
|
|
22
|
+
mattr_reader :pagination_options
|
|
23
|
+
|
|
24
|
+
# Renders Digg-style pagination. (We know you wanna!)
|
|
25
|
+
# Returns nil if there is only one page in total (can't paginate that).
|
|
26
|
+
#
|
|
27
|
+
# Options for will_paginate view helper:
|
|
28
|
+
#
|
|
29
|
+
# class: CSS class name for the generated DIV (default "pagination")
|
|
30
|
+
# prev_label: default '« Previous',
|
|
31
|
+
# next_label: default 'Next »',
|
|
32
|
+
# inner_window: how many links are shown around the current page, defaults to 4
|
|
33
|
+
# outer_window: how many links are around the first and the last page, defaults to 1
|
|
34
|
+
# separator: string separator for page HTML elements, default " " (single space)
|
|
35
|
+
# param_name: parameter name for page number in URLs, defaults to "page"
|
|
36
|
+
#
|
|
37
|
+
# All extra options are passed to the generated container DIV, so eventually
|
|
38
|
+
# they become its HTML attributes.
|
|
39
|
+
#
|
|
40
|
+
def will_paginate(entries = @entries, options = {})
|
|
41
|
+
total_pages = entries.page_count
|
|
42
|
+
|
|
43
|
+
if total_pages > 1
|
|
44
|
+
options = options.symbolize_keys.reverse_merge(pagination_options)
|
|
45
|
+
page, param = entries.current_page, options.delete(:param_name)
|
|
46
|
+
|
|
47
|
+
inner_window, outer_window = options.delete(:inner_window).to_i, options.delete(:outer_window).to_i
|
|
48
|
+
min = page - inner_window
|
|
49
|
+
max = page + inner_window
|
|
50
|
+
# adjust lower or upper limit if other is out of bounds
|
|
51
|
+
if max > total_pages then min -= max - total_pages
|
|
52
|
+
elsif min < 1 then max += 1 - min
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
current = min..max
|
|
56
|
+
beginning = 1..(1 + outer_window)
|
|
57
|
+
tail = (total_pages - outer_window)..total_pages
|
|
58
|
+
visible = [beginning, current, tail].map(&:to_a).flatten.sort.uniq
|
|
59
|
+
links, prev = [], 0
|
|
60
|
+
|
|
61
|
+
visible.each do |n|
|
|
62
|
+
next if n < 1
|
|
63
|
+
break if n > total_pages
|
|
64
|
+
|
|
65
|
+
unless n - prev > 1
|
|
66
|
+
prev = n
|
|
67
|
+
links << page_link_or_span((n != page ? n : nil), 'current', n, param)
|
|
68
|
+
else
|
|
69
|
+
# ellipsis represents the gap between windows
|
|
70
|
+
prev = n - 1
|
|
71
|
+
links << '...'
|
|
72
|
+
redo
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# next and previous buttons
|
|
77
|
+
links.unshift page_link_or_span(entries.previous_page, 'disabled', options.delete(:prev_label), param)
|
|
78
|
+
links.push page_link_or_span(entries.next_page, 'disabled', options.delete(:next_label), param)
|
|
79
|
+
|
|
80
|
+
content_tag :div, links.join(options.delete(:separator)), options
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
protected
|
|
85
|
+
|
|
86
|
+
def page_link_or_span(page, span_class, text, param)
|
|
87
|
+
unless page
|
|
88
|
+
content_tag :span, text, :class => span_class
|
|
89
|
+
else
|
|
90
|
+
# page links should preserve GET parameters, so we merge params
|
|
91
|
+
link_to text, params.merge(param.to_sym => (page !=1 ? page : nil))
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
|
2
|
+
require File.dirname(__FILE__) + '/../init'
|
|
3
|
+
|
|
4
|
+
class ArrayPaginationTest < ActiveRecordTestCase
|
|
5
|
+
def setup
|
|
6
|
+
@array = ('a'..'e').to_a
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
cases = [
|
|
10
|
+
{ :current => 1, :per_page => 3, :expected => %w( a b c ) },
|
|
11
|
+
{ :current => 2, :per_page => 3, :expected => %w( d e ) },
|
|
12
|
+
{ :current => 1, :per_page => 5, :expected => %w( a b c d e ) },
|
|
13
|
+
{ :current => 3, :per_page => 5, :expected => [] },
|
|
14
|
+
{ :current => -1, :per_page => 5, :expected => [] },
|
|
15
|
+
{ :current => 1, :per_page => -5, :expected => [] }
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
cases.each_with_index do |conditions, index|
|
|
19
|
+
define_method("test_case_#{index}") do
|
|
20
|
+
assert_equal conditions[:expected], @array.paginate(conditions[:current], conditions[:per_page])
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
plugin_root = File.join(File.dirname(__FILE__), '..')
|
|
2
|
+
|
|
3
|
+
# first look for a symlink to a copy of the framework
|
|
4
|
+
if framework_root = ["#{plugin_root}/rails", "#{plugin_root}/../../rails"].find { |p| File.directory? p }
|
|
5
|
+
print "found framework root: #{framework_root}"
|
|
6
|
+
# this allows for a plugin to be tested outside an app
|
|
7
|
+
$:.unshift "#{framework_root}/activesupport/lib", "#{framework_root}/activerecord/lib", "#{framework_root}/actionpack/lib"
|
|
8
|
+
else
|
|
9
|
+
# is the plugin installed in an application?
|
|
10
|
+
app_root = plugin_root + '/../../..'
|
|
11
|
+
|
|
12
|
+
if File.directory? app_root + '/config'
|
|
13
|
+
print 'using config/boot.rb'
|
|
14
|
+
ENV['RAILS_ENV'] = 'test'
|
|
15
|
+
require File.expand_path(app_root + '/config/boot')
|
|
16
|
+
else
|
|
17
|
+
# simply use installed gems if available
|
|
18
|
+
print 'using rubygems'
|
|
19
|
+
require 'rubygems'
|
|
20
|
+
gem 'actionpack'; gem 'activerecord'
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
%w(action_pack active_record active_record/version action_controller active_record/fixtures).each {|f| require f}
|
|
25
|
+
puts " (ActiveRecord v#{ActiveRecord::VERSION::STRING})"
|
|
26
|
+
|
|
27
|
+
$:.unshift "#{plugin_root}/lib"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
|
3
|
+
libs = []
|
|
4
|
+
dirname = File.dirname(__FILE__)
|
|
5
|
+
|
|
6
|
+
libs << 'irb/completion'
|
|
7
|
+
libs << File.join(dirname, 'lib', 'load_fixtures')
|
|
8
|
+
libs << File.join(dirname, '..', 'init')
|
|
9
|
+
|
|
10
|
+
exec "#{irb} #{libs.map{|l| " -r #{l}" }.join} --simple-prompt"
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
|
2
|
+
require File.dirname(__FILE__) + '/../init'
|
|
3
|
+
|
|
4
|
+
class FinderTest < ActiveRecordTestCase
|
|
5
|
+
fixtures :topics, :replies, :users, :projects, :developers_projects, :companies
|
|
6
|
+
|
|
7
|
+
def test_new_methods_presence
|
|
8
|
+
assert_respond_to_all Topic, %w(per_page paginate paginate_by_sql)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_paginated_collection
|
|
12
|
+
entries = %w(a b c)
|
|
13
|
+
collection = WillPaginate::Collection.new 2, 3, 10
|
|
14
|
+
collection.replace entries
|
|
15
|
+
|
|
16
|
+
assert_equal entries, collection
|
|
17
|
+
assert_respond_to_all collection, %w(page_count each offset size current_page per_page total_entries)
|
|
18
|
+
assert_equal Array, collection.entries.class
|
|
19
|
+
assert_equal 3, collection.offset
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_simple_paginate
|
|
23
|
+
entries = Topic.paginate :page => nil
|
|
24
|
+
assert_equal 1, entries.current_page
|
|
25
|
+
assert_nil entries.previous_page
|
|
26
|
+
assert_nil entries.next_page
|
|
27
|
+
assert_equal 1, entries.page_count
|
|
28
|
+
assert_equal 4, entries.size
|
|
29
|
+
|
|
30
|
+
entries = Topic.paginate :page => 2
|
|
31
|
+
assert_equal 2, entries.current_page
|
|
32
|
+
assert_equal 1, entries.previous_page
|
|
33
|
+
assert_equal 1, entries.page_count
|
|
34
|
+
assert entries.empty?
|
|
35
|
+
|
|
36
|
+
# :page parameter in options is required!
|
|
37
|
+
assert_raise(ArgumentError){ Topic.paginate }
|
|
38
|
+
assert_raise(ArgumentError){ Topic.paginate({}) }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_paginate_with_per_page
|
|
42
|
+
entries = Topic.paginate :page => 1, :per_page => 1
|
|
43
|
+
assert_equal 1, entries.size
|
|
44
|
+
assert_equal 4, entries.page_count
|
|
45
|
+
|
|
46
|
+
# Developer class has explicit per_page at 10
|
|
47
|
+
entries = Developer.paginate :page => 1
|
|
48
|
+
assert_equal 10, entries.size
|
|
49
|
+
assert_equal 2, entries.page_count
|
|
50
|
+
|
|
51
|
+
entries = Developer.paginate :page => 1, :per_page => 5
|
|
52
|
+
assert_equal 11, entries.total_entries
|
|
53
|
+
assert_equal 5, entries.size
|
|
54
|
+
assert_equal 3, entries.page_count
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_paginate_with_order
|
|
58
|
+
entries = Topic.paginate :page => 1, :order => 'created_at desc'
|
|
59
|
+
expected = [topics(:futurama), topics(:harvey_birdman), topics(:rails), topics(:ar)].reverse
|
|
60
|
+
assert_equal expected, entries.to_a
|
|
61
|
+
assert_equal 1, entries.page_count
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_paginate_with_conditions
|
|
65
|
+
entries = Topic.paginate :page => 1, :conditions => ["created_at > ?", 30.minutes.ago]
|
|
66
|
+
expected = [topics(:rails), topics(:ar)]
|
|
67
|
+
assert_equal expected, entries.to_a
|
|
68
|
+
assert_equal 1, entries.page_count
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def test_paginate_associations
|
|
72
|
+
dhh = users :david
|
|
73
|
+
expected_name_ordered = [projects(:action_controller), projects(:active_record)]
|
|
74
|
+
expected_id_ordered = [projects(:active_record), projects(:action_controller)]
|
|
75
|
+
|
|
76
|
+
# with association-specified order
|
|
77
|
+
entries = dhh.projects.paginate(:page => 1)
|
|
78
|
+
assert_equal expected_name_ordered, entries
|
|
79
|
+
assert_equal 2, entries.total_entries
|
|
80
|
+
|
|
81
|
+
# with explicit order
|
|
82
|
+
entries = dhh.projects.paginate(:page => 1, :order => 'projects.id')
|
|
83
|
+
assert_equal expected_id_ordered, entries
|
|
84
|
+
assert_equal 2, entries.total_entries
|
|
85
|
+
|
|
86
|
+
assert_nothing_raised { dhh.projects.find(:all, :order => 'projects.id', :limit => 4) }
|
|
87
|
+
entries = dhh.projects.paginate(:page => 1, :order => 'projects.id', :per_page => 4)
|
|
88
|
+
assert_equal expected_id_ordered, entries
|
|
89
|
+
|
|
90
|
+
# has_many with implicit order
|
|
91
|
+
topic = Topic.find(1)
|
|
92
|
+
expected = [replies(:spam), replies(:witty_retort)]
|
|
93
|
+
assert_equal expected.map(&:id).sort, topic.replies.paginate(:page => 1).map(&:id).sort
|
|
94
|
+
assert_equal expected.reverse, topic.replies.paginate(:page => 1, :order => 'replies.id ASC')
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def test_paginate_with_joins
|
|
98
|
+
entries = Developer.paginate :page => 1,
|
|
99
|
+
:joins => 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id',
|
|
100
|
+
:conditions => 'project_id = 1'
|
|
101
|
+
assert_equal 2, entries.size
|
|
102
|
+
developer_names = entries.map { |d| d.name }
|
|
103
|
+
assert developer_names.include?('David')
|
|
104
|
+
assert developer_names.include?('Jamis')
|
|
105
|
+
|
|
106
|
+
expected = entries.to_a
|
|
107
|
+
entries = Developer.paginate :page => 1,
|
|
108
|
+
:joins => 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id',
|
|
109
|
+
:conditions => 'project_id = 1', :count => { :select => "users.id" }
|
|
110
|
+
assert_equal expected, entries.to_a
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def test_paginate_with_include_and_order
|
|
114
|
+
entries = Topic.paginate \
|
|
115
|
+
:page => 1,
|
|
116
|
+
:include => :replies,
|
|
117
|
+
:order => 'replies.created_at asc, topics.created_at asc',
|
|
118
|
+
:per_page => 10
|
|
119
|
+
|
|
120
|
+
expected = Topic.find :all,
|
|
121
|
+
:include => 'replies',
|
|
122
|
+
:order => 'replies.created_at asc, topics.created_at asc',
|
|
123
|
+
:limit => 10
|
|
124
|
+
|
|
125
|
+
assert_equal expected, entries.to_a
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def test_paginate_with_group
|
|
129
|
+
entries = Developer.paginate :page => 1, :per_page => 10, :group => 'salary'
|
|
130
|
+
expected = [ users(:david), users(:jamis), users(:dev_10), users(:poor_jamis) ].map(&:salary).sort
|
|
131
|
+
assert_equal expected, entries.map(&:salary).sort
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def test_paginate_with_dynamic_finder
|
|
135
|
+
expected = [replies(:witty_retort), replies(:spam)]
|
|
136
|
+
assert_equal expected, Reply.paginate_all_by_topic_id(1, :page => 1)
|
|
137
|
+
assert_equal expected, Reply.paginate_by_topic_id(1, :page => 1)
|
|
138
|
+
|
|
139
|
+
entries = Developer.paginate :conditions => { :salary => 100000 }, :page => 1, :per_page => 5
|
|
140
|
+
assert_equal 8, entries.total_entries
|
|
141
|
+
assert_equal entries, Developer.paginate_by_salary(100000, :page => 1, :per_page => 5)
|
|
142
|
+
|
|
143
|
+
# dynamic finder + conditions
|
|
144
|
+
entries = Developer.paginate_by_salary(100000, :page => 1,
|
|
145
|
+
:conditions => ['id > ?', 6])
|
|
146
|
+
assert_equal 4, entries.total_entries
|
|
147
|
+
assert_equal (7..10).to_a, entries.map(&:id)
|
|
148
|
+
|
|
149
|
+
assert_raises RuntimeError do
|
|
150
|
+
Developer.paginate_by_inexistent_attribute 100000, :page => 1
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def test_paginate_by_sql
|
|
155
|
+
assert_respond_to Developer, :paginate_by_sql
|
|
156
|
+
entries = Developer.paginate_by_sql ['select * from users where salary > ?', 80000],
|
|
157
|
+
:page => 2, :per_page => 3, :total_entries => 9
|
|
158
|
+
|
|
159
|
+
assert_equal (5..7).to_a, entries.map(&:id)
|
|
160
|
+
assert_equal 9, entries.total_entries
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def test_count_by_sql
|
|
164
|
+
entries = Developer.paginate_by_sql ['select * from users where salary > ?', 60000],
|
|
165
|
+
:page => 2, :per_page => 3
|
|
166
|
+
|
|
167
|
+
assert_equal 12, entries.total_entries
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def test_scoped_paginate
|
|
171
|
+
entries =
|
|
172
|
+
Developer.with_poor_ones do
|
|
173
|
+
Developer.paginate :page => 1
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
assert_equal 2, entries.size
|
|
177
|
+
assert_equal 2, entries.total_entries
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_edge_case_api_madness
|
|
181
|
+
# explicit :all should not break anything
|
|
182
|
+
assert_equal Topic.paginate(:page => nil), Topic.paginate(:all, :page => 1)
|
|
183
|
+
|
|
184
|
+
# this is a little weird test for issue #37
|
|
185
|
+
# the Topic model find and count methods accept an extra option, :foo
|
|
186
|
+
# this checks if that extra option was intact by our paginating finder
|
|
187
|
+
entries = Topic.paginate(:foo => 'bar', :page => 1)
|
|
188
|
+
assert_equal 'bar', entries.first
|
|
189
|
+
assert_equal 100, entries.total_entries
|
|
190
|
+
|
|
191
|
+
# Are we on edge? Find out by testing find_all which was removed in [6998]
|
|
192
|
+
unless Developer.respond_to? :find_all
|
|
193
|
+
# AR finders also accept arrays of IDs
|
|
194
|
+
# (this was broken in Rails before [6912])
|
|
195
|
+
entries = Developer.paginate((1..8).to_a, :per_page => 3, :page => 2)
|
|
196
|
+
assert_equal (4..6).to_a, entries.map(&:id)
|
|
197
|
+
assert_equal 8, entries.total_entries
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def test_count_doesnt_use_select_options
|
|
202
|
+
assert_nothing_raised do
|
|
203
|
+
Developer.paginate :select => 'users.*', :page => 1
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def test_should_use_scoped_finders_if_present
|
|
208
|
+
companies = Company.paginate_best :all, :page => 1
|
|
209
|
+
assert_equal 3, companies.total_entries
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
protected
|
|
213
|
+
|
|
214
|
+
def assert_respond_to_all object, methods
|
|
215
|
+
methods.each do |method|
|
|
216
|
+
[method.to_s, method.to_sym].each {|m| assert_respond_to object, m }
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
thirty_seven_signals:
|
|
2
|
+
id: 1
|
|
3
|
+
name: 37Signals
|
|
4
|
+
rating: 4
|
|
5
|
+
|
|
6
|
+
TextDrive:
|
|
7
|
+
id: 2
|
|
8
|
+
name: TextDrive
|
|
9
|
+
rating: 3
|
|
10
|
+
|
|
11
|
+
PlanetArgon:
|
|
12
|
+
id: 3
|
|
13
|
+
name: Planet Argon
|
|
14
|
+
rating: 3
|
|
15
|
+
|
|
16
|
+
Google:
|
|
17
|
+
id: 4
|
|
18
|
+
name: Google
|
|
19
|
+
rating: 5
|
|
20
|
+
|
|
21
|
+
Ionist:
|
|
22
|
+
id: 5
|
|
23
|
+
name: Ioni.st
|
|
24
|
+
rating: 4
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class Company < ActiveRecord::Base
|
|
2
|
+
attr_protected :rating
|
|
3
|
+
set_sequence_name :companies_nonstd_seq
|
|
4
|
+
|
|
5
|
+
validates_presence_of :name
|
|
6
|
+
def validate
|
|
7
|
+
errors.add('rating', 'rating should not be 2') if rating == 2
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.with_best
|
|
11
|
+
with_scope :find => { :conditions => ['companies.rating > ?', 3] } do
|
|
12
|
+
yield
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.find_best(*args)
|
|
17
|
+
with_best { find(*args) }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.calculate_best(*args)
|
|
21
|
+
with_best { calculate(*args) }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class Developer < User
|
|
2
|
+
has_and_belongs_to_many :projects, :include => :topics, :order => 'projects.name'
|
|
3
|
+
|
|
4
|
+
def self.with_poor_ones(&block)
|
|
5
|
+
with_scope :find => { :conditions => ['salary <= ?', 80000], :order => 'salary' } do
|
|
6
|
+
yield
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.per_page() 10 end
|
|
11
|
+
end
|