Revision 1298:4f746d8966dd lib/plugins
| lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb | ||
|---|---|---|
| 1 | 1 |
# Redmine - project management software |
| 2 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 2 |
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
|
| 3 | 3 |
# |
| 4 | 4 |
# This program is free software; you can redistribute it and/or |
| 5 | 5 |
# modify it under the terms of the GNU General Public License |
| lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb | ||
|---|---|---|
| 1 | 1 |
# Redmine - project management software |
| 2 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 2 |
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
|
| 3 | 3 |
# |
| 4 | 4 |
# This program is free software; you can redistribute it and/or |
| 5 | 5 |
# modify it under the terms of the GNU General Public License |
| ... | ... | |
| 78 | 78 |
end |
| 79 | 79 |
if attachments.is_a?(Array) |
| 80 | 80 |
attachments.each do |attachment| |
| 81 |
next unless attachment.is_a?(Hash) |
|
| 81 | 82 |
a = nil |
| 82 | 83 |
if file = attachment['file'] |
| 83 | 84 |
next unless file.size > 0 |
| lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb | ||
|---|---|---|
| 1 | 1 |
# Redmine - project management software |
| 2 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 2 |
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
|
| 3 | 3 |
# |
| 4 | 4 |
# This program is free software; you can redistribute it and/or |
| 5 | 5 |
# modify it under the terms of the GNU General Public License |
| ... | ... | |
| 32 | 32 |
:order => "#{CustomField.table_name}.position",
|
| 33 | 33 |
:dependent => :delete_all, |
| 34 | 34 |
:validate => false |
| 35 |
|
|
| 35 | 36 |
send :include, Redmine::Acts::Customizable::InstanceMethods |
| 36 | 37 |
validate :validate_custom_field_values |
| 37 | 38 |
after_save :save_custom_field_values |
| ... | ... | |
| 41 | 42 |
module InstanceMethods |
| 42 | 43 |
def self.included(base) |
| 43 | 44 |
base.extend ClassMethods |
| 45 |
base.send :alias_method_chain, :reload, :custom_fields |
|
| 44 | 46 |
end |
| 45 | 47 |
|
| 46 | 48 |
def available_custom_fields |
| 47 |
CustomField.find(:all, :conditions => "type = '#{self.class.name}CustomField'",
|
|
| 48 |
:order => 'position') |
|
| 49 |
CustomField.where("type = '#{self.class.name}CustomField'").sorted.all
|
|
| 49 | 50 |
end |
| 50 | 51 |
|
| 51 | 52 |
# Sets the values of the object's custom fields |
| ... | ... | |
| 153 | 154 |
@custom_field_values_changed = true |
| 154 | 155 |
end |
| 155 | 156 |
|
| 157 |
def reload_with_custom_fields(*args) |
|
| 158 |
@custom_field_values = nil |
|
| 159 |
@custom_field_values_changed = false |
|
| 160 |
reload_without_custom_fields(*args) |
|
| 161 |
end |
|
| 162 |
|
|
| 156 | 163 |
module ClassMethods |
| 157 | 164 |
end |
| 158 | 165 |
end |
| lib/plugins/acts_as_event/lib/acts_as_event.rb | ||
|---|---|---|
| 1 | 1 |
# Redmine - project management software |
| 2 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 2 |
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
|
| 3 | 3 |
# |
| 4 | 4 |
# This program is free software; you can redistribute it and/or |
| 5 | 5 |
# modify it under the terms of the GNU General Public License |
| ... | ... | |
| 63 | 63 |
event_datetime.to_date |
| 64 | 64 |
end |
| 65 | 65 |
|
| 66 |
def event_group |
|
| 67 |
group = event_options[:group] ? send(event_options[:group]) : self |
|
| 68 |
group || self |
|
| 69 |
end |
|
| 70 |
|
|
| 66 | 71 |
def event_url(options = {})
|
| 67 | 72 |
option = event_options[:url] |
| 68 | 73 |
if option.is_a?(Proc) |
| lib/plugins/acts_as_list/lib/active_record/acts/list.rb | ||
|---|---|---|
| 177 | 177 |
# Return the next higher item in the list. |
| 178 | 178 |
def higher_item |
| 179 | 179 |
return nil unless in_list? |
| 180 |
acts_as_list_class.find(:first, :conditions =>
|
|
| 180 |
acts_as_list_class.where(
|
|
| 181 | 181 |
"#{scope_condition} AND #{position_column} = #{(send(position_column).to_i - 1).to_s}"
|
| 182 |
) |
|
| 182 |
).first
|
|
| 183 | 183 |
end |
| 184 | 184 |
|
| 185 | 185 |
# Return the next lower item in the list. |
| 186 | 186 |
def lower_item |
| 187 | 187 |
return nil unless in_list? |
| 188 |
acts_as_list_class.find(:first, :conditions =>
|
|
| 188 |
acts_as_list_class.where(
|
|
| 189 | 189 |
"#{scope_condition} AND #{position_column} = #{(send(position_column).to_i + 1).to_s}"
|
| 190 |
) |
|
| 190 |
).first
|
|
| 191 | 191 |
end |
| 192 | 192 |
|
| 193 | 193 |
# Test if this record is in a list |
| lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb | ||
|---|---|---|
| 1 | 1 |
# Redmine - project management software |
| 2 |
# Copyright (C) 2006-2012 Jean-Philippe Lang
|
|
| 2 |
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
|
| 3 | 3 |
# |
| 4 | 4 |
# This program is free software; you can redistribute it and/or |
| 5 | 5 |
# modify it under the terms of the GNU General Public License |
| ... | ... | |
| 72 | 72 |
tokens = [] << tokens unless tokens.is_a?(Array) |
| 73 | 73 |
projects = [] << projects unless projects.nil? || projects.is_a?(Array) |
| 74 | 74 |
|
| 75 |
find_options = {:include => searchable_options[:include]}
|
|
| 76 |
find_options[:order] = "#{searchable_options[:order_column]} " + (options[:before] ? 'DESC' : 'ASC')
|
|
| 77 |
|
|
| 78 | 75 |
limit_options = {}
|
| 79 | 76 |
limit_options[:limit] = options[:limit] if options[:limit] |
| 80 |
if options[:offset] |
|
| 81 |
limit_options[:conditions] = "(#{searchable_options[:date_column]} " + (options[:before] ? '<' : '>') + "'#{connection.quoted_date(options[:offset])}')"
|
|
| 82 |
end |
|
| 83 | 77 |
|
| 84 | 78 |
columns = searchable_options[:columns] |
| 85 | 79 |
columns = columns[0..0] if options[:titles_only] |
| ... | ... | |
| 87 | 81 |
token_clauses = columns.collect {|column| "(LOWER(#{column}) LIKE ?)"}
|
| 88 | 82 |
|
| 89 | 83 |
if !options[:titles_only] && searchable_options[:search_custom_fields] |
| 90 |
searchable_custom_field_ids = CustomField.find(:all, |
|
| 91 |
:select => 'id', |
|
| 92 |
:conditions => { :type => "#{self.name}CustomField",
|
|
| 93 |
:searchable => true }).collect(&:id) |
|
| 84 |
searchable_custom_field_ids = CustomField.where(:type => "#{self.name}CustomField", :searchable => true).pluck(:id)
|
|
| 94 | 85 |
if searchable_custom_field_ids.any? |
| 95 | 86 |
custom_field_sql = "#{table_name}.id IN (SELECT customized_id FROM #{CustomValue.table_name}" +
|
| 96 | 87 |
" WHERE customized_type='#{self.name}' AND customized_id=#{table_name}.id AND LOWER(value) LIKE ?" +
|
| ... | ... | |
| 101 | 92 |
|
| 102 | 93 |
sql = (['(' + token_clauses.join(' OR ') + ')'] * tokens.size).join(options[:all_words] ? ' AND ' : ' OR ')
|
| 103 | 94 |
|
| 104 |
find_options[:conditions] = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort]
|
|
| 95 |
tokens_conditions = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort]
|
|
| 105 | 96 |
|
| 106 |
scope = self |
|
| 97 |
scope = self.scoped
|
|
| 107 | 98 |
project_conditions = [] |
| 108 | 99 |
if searchable_options.has_key?(:permission) |
| 109 | 100 |
project_conditions << Project.allowed_to_condition(user, searchable_options[:permission] || :view_project) |
| ... | ... | |
| 120 | 111 |
results = [] |
| 121 | 112 |
results_count = 0 |
| 122 | 113 |
|
| 123 |
scope = scope.scoped({:conditions => project_conditions}).scoped(find_options)
|
|
| 124 |
results_count = scope.count(:all) |
|
| 125 |
results = scope.find(:all, limit_options) |
|
| 114 |
scope = scope. |
|
| 115 |
includes(searchable_options[:include]). |
|
| 116 |
order("#{searchable_options[:order_column]} " + (options[:before] ? 'DESC' : 'ASC')).
|
|
| 117 |
where(project_conditions). |
|
| 118 |
where(tokens_conditions) |
|
| 119 |
|
|
| 120 |
results_count = scope.count |
|
| 121 |
|
|
| 122 |
scope_with_limit = scope.limit(options[:limit]) |
|
| 123 |
if options[:offset] |
|
| 124 |
scope_with_limit = scope_with_limit.where("#{searchable_options[:date_column]} #{options[:before] ? '<' : '>'} ?", options[:offset])
|
|
| 125 |
end |
|
| 126 |
results = scope_with_limit.all |
|
| 126 | 127 |
|
| 127 | 128 |
[results, results_count] |
| 128 | 129 |
end |
| lib/plugins/acts_as_tree/lib/active_record/acts/tree.rb | ||
|---|---|---|
| 46 | 46 |
belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache] |
| 47 | 47 |
has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => configuration[:dependent] |
| 48 | 48 |
|
| 49 |
class_eval <<-EOV |
|
| 50 |
include ActiveRecord::Acts::Tree::InstanceMethods |
|
| 49 |
scope :roots, where("#{configuration[:foreign_key]} IS NULL").order(configuration[:order])
|
|
| 51 | 50 |
|
| 52 |
def self.roots |
|
| 53 |
find(:all, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
|
|
| 54 |
end |
|
| 55 |
|
|
| 56 |
def self.root |
|
| 57 |
find(:first, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
|
|
| 58 |
end |
|
| 59 |
EOV |
|
| 51 |
send :include, ActiveRecord::Acts::Tree::InstanceMethods |
|
| 60 | 52 |
end |
| 61 | 53 |
end |
| 62 | 54 |
|
| lib/plugins/acts_as_versioned/lib/acts_as_versioned.rb | ||
|---|---|---|
| 216 | 216 |
has_many :versions, version_association_options do |
| 217 | 217 |
# finds earliest version of this record |
| 218 | 218 |
def earliest |
| 219 |
@earliest ||= find(:first, :order => 'version')
|
|
| 219 |
@earliest ||= order('version').first
|
|
| 220 | 220 |
end |
| 221 | 221 |
|
| 222 | 222 |
# find latest version of this record |
| 223 | 223 |
def latest |
| 224 |
@latest ||= find(:first, :order => 'version desc')
|
|
| 224 |
@latest ||= order('version desc').first
|
|
| 225 | 225 |
end |
| 226 | 226 |
end |
| 227 | 227 |
before_save :set_new_version |
| ... | ... | |
| 248 | 248 |
def self.reloadable? ; false ; end |
| 249 | 249 |
# find first version before the given version |
| 250 | 250 |
def self.before(version) |
| 251 |
find :first, :order => 'version desc', |
|
| 252 |
:conditions => ["#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version]
|
|
| 251 |
order('version desc').
|
|
| 252 |
where("#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version).
|
|
| 253 |
first |
|
| 253 | 254 |
end |
| 254 | 255 |
|
| 255 | 256 |
# find first version after the given version. |
| 256 | 257 |
def self.after(version) |
| 257 |
find :first, :order => 'version', |
|
| 258 |
:conditions => ["#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version]
|
|
| 258 |
order('version').
|
|
| 259 |
where("#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version).
|
|
| 260 |
first |
|
| 259 | 261 |
end |
| 260 | 262 |
|
| 261 | 263 |
def previous |
| ... | ... | |
| 467 | 469 |
|
| 468 | 470 |
# Finds versions of a specific model. Takes an options hash like <tt>find</tt> |
| 469 | 471 |
def find_versions(id, options = {})
|
| 470 |
versioned_class.find :all, {
|
|
| 472 |
versioned_class.all({
|
|
| 471 | 473 |
:conditions => ["#{versioned_foreign_key} = ?", id],
|
| 472 |
:order => 'version' }.merge(options) |
|
| 474 |
:order => 'version' }.merge(options))
|
|
| 473 | 475 |
end |
| 474 | 476 |
|
| 475 | 477 |
# Returns an array of columns that are versioned. See non_versioned_columns |
| lib/plugins/awesome_nested_set/lib/awesome_nested_set/awesome_nested_set.rb | ||
|---|---|---|
| 413 | 413 |
|
| 414 | 414 |
# on creation, set automatically lft and rgt to the end of the tree |
| 415 | 415 |
def set_default_left_and_right |
| 416 |
highest_right_row = nested_set_scope(:order => "#{quoted_right_column_name} desc").find(:first, :limit => 1,:lock => true )
|
|
| 416 |
highest_right_row = nested_set_scope(:order => "#{quoted_right_column_name} desc").limit(1).lock(true).first
|
|
| 417 | 417 |
maxright = highest_right_row ? (highest_right_row[right_column_name] || 0) : 0 |
| 418 | 418 |
# adds the new node to the right of all existing nodes |
| 419 | 419 |
self[left_column_name] = maxright + 1 |
| ... | ... | |
| 443 | 443 |
in_tenacious_transaction do |
| 444 | 444 |
reload_nested_set |
| 445 | 445 |
# select the rows in the model that extend past the deletion point and apply a lock |
| 446 |
self.class.base_class.find(:all,
|
|
| 447 |
:select => "id",
|
|
| 448 |
:conditions => ["#{quoted_left_column_name} >= ?", left],
|
|
| 449 |
:lock => true
|
|
| 450 |
)
|
|
| 446 |
self.class.base_class. |
|
| 447 |
select("id").
|
|
| 448 |
where("#{quoted_left_column_name} >= ?", left).
|
|
| 449 |
lock(true).
|
|
| 450 |
all
|
|
| 451 | 451 |
|
| 452 | 452 |
if acts_as_nested_set_options[:dependent] == :destroy |
| 453 | 453 |
descendants.each do |model| |
| lib/plugins/classic_pagination/CHANGELOG | ||
|---|---|---|
| 1 |
* Exported the changelog of Pagination code for historical reference. |
|
| 2 |
|
|
| 3 |
* Imported some patches from Rails Trac (others closed as "wontfix"): |
|
| 4 |
#8176, #7325, #7028, #4113. Documentation is much cleaner now and there |
|
| 5 |
are some new unobtrusive features! |
|
| 6 |
|
|
| 7 |
* Extracted Pagination from Rails trunk (r6795) |
|
| 8 |
|
|
| 9 |
# |
|
| 10 |
# ChangeLog for /trunk/actionpack/lib/action_controller/pagination.rb |
|
| 11 |
# |
|
| 12 |
# Generated by Trac 0.10.3 |
|
| 13 |
# 05/20/07 23:48:02 |
|
| 14 |
# |
|
| 15 |
|
|
| 16 |
09/03/06 23:28:54 david [4953] |
|
| 17 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 18 |
Docs and deprecation |
|
| 19 |
|
|
| 20 |
08/07/06 12:40:14 bitsweat [4715] |
|
| 21 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 22 |
Deprecate direct usage of @params. Update ActionView::Base for |
|
| 23 |
instance var deprecation. |
|
| 24 |
|
|
| 25 |
06/21/06 02:16:11 rick [4476] |
|
| 26 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 27 |
Fix indent in pagination documentation. Closes #4990. [Kevin Clark] |
|
| 28 |
|
|
| 29 |
04/25/06 17:42:48 marcel [4268] |
|
| 30 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 31 |
Remove all remaining references to @params in the documentation. |
|
| 32 |
|
|
| 33 |
03/16/06 06:38:08 rick [3899] |
|
| 34 |
* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified) |
|
| 35 |
trivial documentation patch for #pagination_links [Francois |
|
| 36 |
Beausoleil] closes #4258 |
|
| 37 |
|
|
| 38 |
02/20/06 03:15:22 david [3620] |
|
| 39 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 40 |
* trunk/actionpack/test/activerecord/pagination_test.rb (modified) |
|
| 41 |
* trunk/activerecord/CHANGELOG (modified) |
|
| 42 |
* trunk/activerecord/lib/active_record/base.rb (modified) |
|
| 43 |
* trunk/activerecord/test/base_test.rb (modified) |
|
| 44 |
Added :count option to pagination that'll make it possible for the |
|
| 45 |
ActiveRecord::Base.count call to using something else than * for the |
|
| 46 |
count. Especially important for count queries using DISTINCT #3839 |
|
| 47 |
[skaes]. Added :select option to Base.count that'll allow you to |
|
| 48 |
select something else than * to be counted on. Especially important |
|
| 49 |
for count queries using DISTINCT (closes #3839) [skaes]. |
|
| 50 |
|
|
| 51 |
02/09/06 09:17:40 nzkoz [3553] |
|
| 52 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 53 |
* trunk/actionpack/test/active_record_unit.rb (added) |
|
| 54 |
* trunk/actionpack/test/activerecord (added) |
|
| 55 |
* trunk/actionpack/test/activerecord/active_record_assertions_test.rb (added) |
|
| 56 |
* trunk/actionpack/test/activerecord/pagination_test.rb (added) |
|
| 57 |
* trunk/actionpack/test/controller/active_record_assertions_test.rb (deleted) |
|
| 58 |
* trunk/actionpack/test/fixtures/companies.yml (added) |
|
| 59 |
* trunk/actionpack/test/fixtures/company.rb (added) |
|
| 60 |
* trunk/actionpack/test/fixtures/db_definitions (added) |
|
| 61 |
* trunk/actionpack/test/fixtures/db_definitions/sqlite.sql (added) |
|
| 62 |
* trunk/actionpack/test/fixtures/developer.rb (added) |
|
| 63 |
* trunk/actionpack/test/fixtures/developers_projects.yml (added) |
|
| 64 |
* trunk/actionpack/test/fixtures/developers.yml (added) |
|
| 65 |
* trunk/actionpack/test/fixtures/project.rb (added) |
|
| 66 |
* trunk/actionpack/test/fixtures/projects.yml (added) |
|
| 67 |
* trunk/actionpack/test/fixtures/replies.yml (added) |
|
| 68 |
* trunk/actionpack/test/fixtures/reply.rb (added) |
|
| 69 |
* trunk/actionpack/test/fixtures/topic.rb (added) |
|
| 70 |
* trunk/actionpack/test/fixtures/topics.yml (added) |
|
| 71 |
* Fix pagination problems when using include |
|
| 72 |
* Introduce Unit Tests for pagination |
|
| 73 |
* Allow count to work with :include by using count distinct. |
|
| 74 |
|
|
| 75 |
[Kevin Clark & Jeremy Hopple] |
|
| 76 |
|
|
| 77 |
11/05/05 02:10:29 bitsweat [2878] |
|
| 78 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 79 |
Update paginator docs. Closes #2744. |
|
| 80 |
|
|
| 81 |
10/16/05 15:42:03 minam [2649] |
|
| 82 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 83 |
Update/clean up AP documentation (rdoc) |
|
| 84 |
|
|
| 85 |
08/31/05 00:13:10 ulysses [2078] |
|
| 86 |
* trunk/actionpack/CHANGELOG (modified) |
|
| 87 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 88 |
Add option to specify the singular name used by pagination. Closes |
|
| 89 |
#1960 |
|
| 90 |
|
|
| 91 |
08/23/05 14:24:15 minam [2041] |
|
| 92 |
* trunk/actionpack/CHANGELOG (modified) |
|
| 93 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 94 |
Add support for :include with pagination (subject to existing |
|
| 95 |
constraints for :include with :limit and :offset) #1478 |
|
| 96 |
[michael@schubert.cx] |
|
| 97 |
|
|
| 98 |
07/15/05 20:27:38 david [1839] |
|
| 99 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 100 |
* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified) |
|
| 101 |
More pagination speed #1334 [Stefan Kaes] |
|
| 102 |
|
|
| 103 |
07/14/05 08:02:01 david [1832] |
|
| 104 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 105 |
* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified) |
|
| 106 |
* trunk/actionpack/test/controller/addresses_render_test.rb (modified) |
|
| 107 |
Made pagination faster #1334 [Stefan Kaes] |
|
| 108 |
|
|
| 109 |
04/13/05 05:40:22 david [1159] |
|
| 110 |
* trunk/actionpack/CHANGELOG (modified) |
|
| 111 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 112 |
* trunk/activerecord/lib/active_record/base.rb (modified) |
|
| 113 |
Fixed pagination to work with joins #1034 [scott@sigkill.org] |
|
| 114 |
|
|
| 115 |
04/02/05 09:11:17 david [1067] |
|
| 116 |
* trunk/actionpack/CHANGELOG (modified) |
|
| 117 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 118 |
* trunk/actionpack/lib/action_controller/scaffolding.rb (modified) |
|
| 119 |
* trunk/actionpack/lib/action_controller/templates/scaffolds/list.rhtml (modified) |
|
| 120 |
* trunk/railties/lib/rails_generator/generators/components/scaffold/templates/controller.rb (modified) |
|
| 121 |
* trunk/railties/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml (modified) |
|
| 122 |
Added pagination for scaffolding (10 items per page) #964 |
|
| 123 |
[mortonda@dgrmm.net] |
|
| 124 |
|
|
| 125 |
03/31/05 14:46:11 david [1048] |
|
| 126 |
* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified) |
|
| 127 |
Improved the message display on the exception handler pages #963 |
|
| 128 |
[Johan Sorensen] |
|
| 129 |
|
|
| 130 |
03/27/05 00:04:07 david [1017] |
|
| 131 |
* trunk/actionpack/CHANGELOG (modified) |
|
| 132 |
* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified) |
|
| 133 |
Fixed that pagination_helper would ignore :params #947 [Sebastian |
|
| 134 |
Kanthak] |
|
| 135 |
|
|
| 136 |
03/22/05 13:09:44 david [976] |
|
| 137 |
* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified) |
|
| 138 |
Fixed documentation and prepared for 0.11.0 release |
|
| 139 |
|
|
| 140 |
03/21/05 14:35:36 david [967] |
|
| 141 |
* trunk/actionpack/lib/action_controller/pagination.rb (modified) |
|
| 142 |
* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified) |
|
| 143 |
Tweaked the documentation |
|
| 144 |
|
|
| 145 |
03/20/05 23:12:05 david [949] |
|
| 146 |
* trunk/actionpack/CHANGELOG (modified) |
|
| 147 |
* trunk/actionpack/lib/action_controller.rb (modified) |
|
| 148 |
* trunk/actionpack/lib/action_controller/pagination.rb (added) |
|
| 149 |
* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (added) |
|
| 150 |
* trunk/activesupport/lib/active_support/core_ext/kernel.rb (added) |
|
| 151 |
Added pagination support through both a controller and helper add-on |
|
| 152 |
#817 [Sam Stephenson] |
|
| lib/plugins/classic_pagination/README | ||
|---|---|---|
| 1 |
Pagination |
|
| 2 |
========== |
|
| 3 |
|
|
| 4 |
To install: |
|
| 5 |
|
|
| 6 |
script/plugin install svn://errtheblog.com/svn/plugins/classic_pagination |
|
| 7 |
|
|
| 8 |
This code was extracted from Rails trunk after the release 1.2.3. |
|
| 9 |
WARNING: this code is dead. It is unmaintained, untested and full of cruft. |
|
| 10 |
|
|
| 11 |
There is a much better pagination plugin called will_paginate. |
|
| 12 |
Install it like this and glance through the README: |
|
| 13 |
|
|
| 14 |
script/plugin install svn://errtheblog.com/svn/plugins/will_paginate |
|
| 15 |
|
|
| 16 |
It doesn't have the same API, but is in fact much nicer. You can |
|
| 17 |
have both plugins installed until you change your controller/view code that |
|
| 18 |
handles pagination. Then, simply uninstall classic_pagination. |
|
| lib/plugins/classic_pagination/Rakefile | ||
|---|---|---|
| 1 |
require 'rake' |
|
| 2 |
require 'rake/testtask' |
|
| 3 |
require 'rake/rdoctask' |
|
| 4 |
|
|
| 5 |
desc 'Default: run unit tests.' |
|
| 6 |
task :default => :test |
|
| 7 |
|
|
| 8 |
desc 'Test the classic_pagination plugin.' |
|
| 9 |
Rake::TestTask.new(:test) do |t| |
|
| 10 |
t.libs << 'lib' |
|
| 11 |
t.pattern = 'test/**/*_test.rb' |
|
| 12 |
t.verbose = true |
|
| 13 |
end |
|
| 14 |
|
|
| 15 |
desc 'Generate documentation for the classic_pagination plugin.' |
|
| 16 |
Rake::RDocTask.new(:rdoc) do |rdoc| |
|
| 17 |
rdoc.rdoc_dir = 'rdoc' |
|
| 18 |
rdoc.title = 'Pagination' |
|
| 19 |
rdoc.options << '--line-numbers' << '--inline-source' |
|
| 20 |
rdoc.rdoc_files.include('README')
|
|
| 21 |
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
| 22 |
end |
|
| lib/plugins/classic_pagination/init.rb | ||
|---|---|---|
| 1 |
#-- |
|
| 2 |
# Copyright (c) 2004-2006 David Heinemeier Hansson |
|
| 3 |
# |
|
| 4 |
# Permission is hereby granted, free of charge, to any person obtaining |
|
| 5 |
# a copy of this software and associated documentation files (the |
|
| 6 |
# "Software"), to deal in the Software without restriction, including |
|
| 7 |
# without limitation the rights to use, copy, modify, merge, publish, |
|
| 8 |
# distribute, sublicense, and/or sell copies of the Software, and to |
|
| 9 |
# permit persons to whom the Software is furnished to do so, subject to |
|
| 10 |
# the following conditions: |
|
| 11 |
# |
|
| 12 |
# The above copyright notice and this permission notice shall be |
|
| 13 |
# included in all copies or substantial portions of the Software. |
|
| 14 |
# |
|
| 15 |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
| 16 |
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
| 17 |
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
| 18 |
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
|
| 19 |
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
|
| 20 |
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
| 21 |
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
| 22 |
#++ |
|
| 23 |
|
|
| 24 |
require 'pagination' |
|
| 25 |
require 'pagination_helper' |
|
| 26 |
|
|
| 27 |
ActionController::Base.class_eval do |
|
| 28 |
include ActionController::Pagination |
|
| 29 |
end |
|
| 30 |
|
|
| 31 |
ActionView::Base.class_eval do |
|
| 32 |
include ActionView::Helpers::PaginationHelper |
|
| 33 |
end |
|
| lib/plugins/classic_pagination/install.rb | ||
|---|---|---|
| 1 |
puts "\n\n" + File.read(File.dirname(__FILE__) + '/README') |
|
| lib/plugins/classic_pagination/lib/pagination.rb | ||
|---|---|---|
| 1 |
module ActionController |
|
| 2 |
# === Action Pack pagination for Active Record collections |
|
| 3 |
# |
|
| 4 |
# The Pagination module aids in the process of paging large collections of |
|
| 5 |
# Active Record objects. It offers macro-style automatic fetching of your |
|
| 6 |
# model for multiple views, or explicit fetching for single actions. And if |
|
| 7 |
# the magic isn't flexible enough for your needs, you can create your own |
|
| 8 |
# paginators with a minimal amount of code. |
|
| 9 |
# |
|
| 10 |
# The Pagination module can handle as much or as little as you wish. In the |
|
| 11 |
# controller, have it automatically query your model for pagination; or, |
|
| 12 |
# if you prefer, create Paginator objects yourself. |
|
| 13 |
# |
|
| 14 |
# Pagination is included automatically for all controllers. |
|
| 15 |
# |
|
| 16 |
# For help rendering pagination links, see |
|
| 17 |
# ActionView::Helpers::PaginationHelper. |
|
| 18 |
# |
|
| 19 |
# ==== Automatic pagination for every action in a controller |
|
| 20 |
# |
|
| 21 |
# class PersonController < ApplicationController |
|
| 22 |
# model :person |
|
| 23 |
# |
|
| 24 |
# paginate :people, :order => 'last_name, first_name', |
|
| 25 |
# :per_page => 20 |
|
| 26 |
# |
|
| 27 |
# # ... |
|
| 28 |
# end |
|
| 29 |
# |
|
| 30 |
# Each action in this controller now has access to a <tt>@people</tt> |
|
| 31 |
# instance variable, which is an ordered collection of model objects for the |
|
| 32 |
# current page (at most 20, sorted by last name and first name), and a |
|
| 33 |
# <tt>@person_pages</tt> Paginator instance. The current page is determined |
|
| 34 |
# by the <tt>params[:page]</tt> variable. |
|
| 35 |
# |
|
| 36 |
# ==== Pagination for a single action |
|
| 37 |
# |
|
| 38 |
# def list |
|
| 39 |
# @person_pages, @people = |
|
| 40 |
# paginate :people, :order => 'last_name, first_name' |
|
| 41 |
# end |
|
| 42 |
# |
|
| 43 |
# Like the previous example, but explicitly creates <tt>@person_pages</tt> |
|
| 44 |
# and <tt>@people</tt> for a single action, and uses the default of 10 items |
|
| 45 |
# per page. |
|
| 46 |
# |
|
| 47 |
# ==== Custom/"classic" pagination |
|
| 48 |
# |
|
| 49 |
# def list |
|
| 50 |
# @person_pages = Paginator.new self, Person.count, 10, params[:page] |
|
| 51 |
# @people = Person.find :all, :order => 'last_name, first_name', |
|
| 52 |
# :limit => @person_pages.items_per_page, |
|
| 53 |
# :offset => @person_pages.current.offset |
|
| 54 |
# end |
|
| 55 |
# |
|
| 56 |
# Explicitly creates the paginator from the previous example and uses |
|
| 57 |
# Paginator#to_sql to retrieve <tt>@people</tt> from the model. |
|
| 58 |
# |
|
| 59 |
module Pagination |
|
| 60 |
unless const_defined?(:OPTIONS) |
|
| 61 |
# A hash holding options for controllers using macro-style pagination |
|
| 62 |
OPTIONS = Hash.new |
|
| 63 |
|
|
| 64 |
# The default options for pagination |
|
| 65 |
DEFAULT_OPTIONS = {
|
|
| 66 |
:class_name => nil, |
|
| 67 |
:singular_name => nil, |
|
| 68 |
:per_page => 10, |
|
| 69 |
:conditions => nil, |
|
| 70 |
:order_by => nil, |
|
| 71 |
:order => nil, |
|
| 72 |
:join => nil, |
|
| 73 |
:joins => nil, |
|
| 74 |
:count => nil, |
|
| 75 |
:include => nil, |
|
| 76 |
:select => nil, |
|
| 77 |
:group => nil, |
|
| 78 |
:parameter => 'page' |
|
| 79 |
} |
|
| 80 |
else |
|
| 81 |
DEFAULT_OPTIONS[:group] = nil |
|
| 82 |
end |
|
| 83 |
|
|
| 84 |
def self.included(base) #:nodoc: |
|
| 85 |
super |
|
| 86 |
base.extend(ClassMethods) |
|
| 87 |
end |
|
| 88 |
|
|
| 89 |
def self.validate_options!(collection_id, options, in_action) #:nodoc: |
|
| 90 |
options.merge!(DEFAULT_OPTIONS) {|key, old, new| old}
|
|
| 91 |
|
|
| 92 |
valid_options = DEFAULT_OPTIONS.keys |
|
| 93 |
valid_options << :actions unless in_action |
|
| 94 |
|
|
| 95 |
unknown_option_keys = options.keys - valid_options |
|
| 96 |
raise ActionController::ActionControllerError, |
|
| 97 |
"Unknown options: #{unknown_option_keys.join(', ')}" unless
|
|
| 98 |
unknown_option_keys.empty? |
|
| 99 |
|
|
| 100 |
options[:singular_name] ||= ActiveSupport::Inflector.singularize(collection_id.to_s) |
|
| 101 |
options[:class_name] ||= ActiveSupport::Inflector.camelize(options[:singular_name]) |
|
| 102 |
end |
|
| 103 |
|
|
| 104 |
# Returns a paginator and a collection of Active Record model instances |
|
| 105 |
# for the paginator's current page. This is designed to be used in a |
|
| 106 |
# single action; to automatically paginate multiple actions, consider |
|
| 107 |
# ClassMethods#paginate. |
|
| 108 |
# |
|
| 109 |
# +options+ are: |
|
| 110 |
# <tt>:singular_name</tt>:: the singular name to use, if it can't be inferred by singularizing the collection name |
|
| 111 |
# <tt>:class_name</tt>:: the class name to use, if it can't be inferred by |
|
| 112 |
# camelizing the singular name |
|
| 113 |
# <tt>:per_page</tt>:: the maximum number of items to include in a |
|
| 114 |
# single page. Defaults to 10 |
|
| 115 |
# <tt>:conditions</tt>:: optional conditions passed to Model.find(:all, *params) and |
|
| 116 |
# Model.count |
|
| 117 |
# <tt>:order</tt>:: optional order parameter passed to Model.find(:all, *params) |
|
| 118 |
# <tt>:order_by</tt>:: (deprecated, used :order) optional order parameter passed to Model.find(:all, *params) |
|
| 119 |
# <tt>:joins</tt>:: optional joins parameter passed to Model.find(:all, *params) |
|
| 120 |
# and Model.count |
|
| 121 |
# <tt>:join</tt>:: (deprecated, used :joins or :include) optional join parameter passed to Model.find(:all, *params) |
|
| 122 |
# and Model.count |
|
| 123 |
# <tt>:include</tt>:: optional eager loading parameter passed to Model.find(:all, *params) |
|
| 124 |
# and Model.count |
|
| 125 |
# <tt>:select</tt>:: :select parameter passed to Model.find(:all, *params) |
|
| 126 |
# |
|
| 127 |
# <tt>:count</tt>:: parameter passed as :select option to Model.count(*params) |
|
| 128 |
# |
|
| 129 |
# <tt>:group</tt>:: :group parameter passed to Model.find(:all, *params). It forces the use of DISTINCT instead of plain COUNT to come up with the total number of records |
|
| 130 |
# |
|
| 131 |
def paginate(collection_id, options={})
|
|
| 132 |
Pagination.validate_options!(collection_id, options, true) |
|
| 133 |
paginator_and_collection_for(collection_id, options) |
|
| 134 |
end |
|
| 135 |
|
|
| 136 |
# These methods become class methods on any controller |
|
| 137 |
module ClassMethods |
|
| 138 |
# Creates a +before_filter+ which automatically paginates an Active |
|
| 139 |
# Record model for all actions in a controller (or certain actions if |
|
| 140 |
# specified with the <tt>:actions</tt> option). |
|
| 141 |
# |
|
| 142 |
# +options+ are the same as PaginationHelper#paginate, with the addition |
|
| 143 |
# of: |
|
| 144 |
# <tt>:actions</tt>:: an array of actions for which the pagination is |
|
| 145 |
# active. Defaults to +nil+ (i.e., every action) |
|
| 146 |
def paginate(collection_id, options={})
|
|
| 147 |
Pagination.validate_options!(collection_id, options, false) |
|
| 148 |
module_eval do |
|
| 149 |
before_filter :create_paginators_and_retrieve_collections |
|
| 150 |
OPTIONS[self] ||= Hash.new |
|
| 151 |
OPTIONS[self][collection_id] = options |
|
| 152 |
end |
|
| 153 |
end |
|
| 154 |
end |
|
| 155 |
|
|
| 156 |
def create_paginators_and_retrieve_collections #:nodoc: |
|
| 157 |
Pagination::OPTIONS[self.class].each do |collection_id, options| |
|
| 158 |
next unless options[:actions].include? action_name if |
|
| 159 |
options[:actions] |
|
| 160 |
|
|
| 161 |
paginator, collection = |
|
| 162 |
paginator_and_collection_for(collection_id, options) |
|
| 163 |
|
|
| 164 |
paginator_name = "@#{options[:singular_name]}_pages"
|
|
| 165 |
self.instance_variable_set(paginator_name, paginator) |
|
| 166 |
|
|
| 167 |
collection_name = "@#{collection_id.to_s}"
|
|
| 168 |
self.instance_variable_set(collection_name, collection) |
|
| 169 |
end |
|
| 170 |
end |
|
| 171 |
|
|
| 172 |
# Returns the total number of items in the collection to be paginated for |
|
| 173 |
# the +model+ and given +conditions+. Override this method to implement a |
|
| 174 |
# custom counter. |
|
| 175 |
def count_collection_for_pagination(model, options) |
|
| 176 |
model.count(:conditions => options[:conditions], |
|
| 177 |
:joins => options[:join] || options[:joins], |
|
| 178 |
:include => options[:include], |
|
| 179 |
:select => (options[:group] ? "DISTINCT #{options[:group]}" : options[:count]))
|
|
| 180 |
end |
|
| 181 |
|
|
| 182 |
# Returns a collection of items for the given +model+ and +options[conditions]+, |
|
| 183 |
# ordered by +options[order]+, for the current page in the given +paginator+. |
|
| 184 |
# Override this method to implement a custom finder. |
|
| 185 |
def find_collection_for_pagination(model, options, paginator) |
|
| 186 |
model.find(:all, :conditions => options[:conditions], |
|
| 187 |
:order => options[:order_by] || options[:order], |
|
| 188 |
:joins => options[:join] || options[:joins], :include => options[:include], |
|
| 189 |
:select => options[:select], :limit => options[:per_page], |
|
| 190 |
:group => options[:group], :offset => paginator.current.offset) |
|
| 191 |
end |
|
| 192 |
|
|
| 193 |
protected :create_paginators_and_retrieve_collections, |
|
| 194 |
:count_collection_for_pagination, |
|
| 195 |
:find_collection_for_pagination |
|
| 196 |
|
|
| 197 |
def paginator_and_collection_for(collection_id, options) #:nodoc: |
|
| 198 |
klass = options[:class_name].constantize |
|
| 199 |
page = params[options[:parameter]] |
|
| 200 |
count = count_collection_for_pagination(klass, options) |
|
| 201 |
paginator = Paginator.new(self, count, options[:per_page], page) |
|
| 202 |
collection = find_collection_for_pagination(klass, options, paginator) |
|
| 203 |
|
|
| 204 |
return paginator, collection |
|
| 205 |
end |
|
| 206 |
|
|
| 207 |
private :paginator_and_collection_for |
|
| 208 |
|
|
| 209 |
# A class representing a paginator for an Active Record collection. |
|
| 210 |
class Paginator |
|
| 211 |
include Enumerable |
|
| 212 |
|
|
| 213 |
# Creates a new Paginator on the given +controller+ for a set of items |
|
| 214 |
# of size +item_count+ and having +items_per_page+ items per page. |
|
| 215 |
# Raises ArgumentError if items_per_page is out of bounds (i.e., less |
|
| 216 |
# than or equal to zero). The page CGI parameter for links defaults to |
|
| 217 |
# "page" and can be overridden with +page_parameter+. |
|
| 218 |
def initialize(controller, item_count, items_per_page, current_page=1) |
|
| 219 |
raise ArgumentError, 'must have at least one item per page' if |
|
| 220 |
items_per_page <= 0 |
|
| 221 |
|
|
| 222 |
@controller = controller |
|
| 223 |
@item_count = item_count || 0 |
|
| 224 |
@items_per_page = items_per_page |
|
| 225 |
@pages = {}
|
|
| 226 |
|
|
| 227 |
self.current_page = current_page |
|
| 228 |
end |
|
| 229 |
attr_reader :controller, :item_count, :items_per_page |
|
| 230 |
|
|
| 231 |
# Sets the current page number of this paginator. If +page+ is a Page |
|
| 232 |
# object, its +number+ attribute is used as the value; if the page does |
|
| 233 |
# not belong to this Paginator, an ArgumentError is raised. |
|
| 234 |
def current_page=(page) |
|
| 235 |
if page.is_a? Page |
|
| 236 |
raise ArgumentError, 'Page/Paginator mismatch' unless |
|
| 237 |
page.paginator == self |
|
| 238 |
end |
|
| 239 |
page = page.to_i |
|
| 240 |
@current_page_number = has_page_number?(page) ? page : 1 |
|
| 241 |
end |
|
| 242 |
|
|
| 243 |
# Returns a Page object representing this paginator's current page. |
|
| 244 |
def current_page |
|
| 245 |
@current_page ||= self[@current_page_number] |
|
| 246 |
end |
|
| 247 |
alias current :current_page |
|
| 248 |
|
|
| 249 |
# Returns a new Page representing the first page in this paginator. |
|
| 250 |
def first_page |
|
| 251 |
@first_page ||= self[1] |
|
| 252 |
end |
|
| 253 |
alias first :first_page |
|
| 254 |
|
|
| 255 |
# Returns a new Page representing the last page in this paginator. |
|
| 256 |
def last_page |
|
| 257 |
@last_page ||= self[page_count] |
|
| 258 |
end |
|
| 259 |
alias last :last_page |
|
| 260 |
|
|
| 261 |
# Returns the number of pages in this paginator. |
|
| 262 |
def page_count |
|
| 263 |
@page_count ||= @item_count.zero? ? 1 : |
|
| 264 |
(q,r=@item_count.divmod(@items_per_page); r==0? q : q+1) |
|
| 265 |
end |
|
| 266 |
|
|
| 267 |
alias length :page_count |
|
| 268 |
|
|
| 269 |
# Returns true if this paginator contains the page of index +number+. |
|
| 270 |
def has_page_number?(number) |
|
| 271 |
number >= 1 and number <= page_count |
|
| 272 |
end |
|
| 273 |
|
|
| 274 |
# Returns a new Page representing the page with the given index |
|
| 275 |
# +number+. |
|
| 276 |
def [](number) |
|
| 277 |
@pages[number] ||= Page.new(self, number) |
|
| 278 |
end |
|
| 279 |
|
|
| 280 |
# Successively yields all the paginator's pages to the given block. |
|
| 281 |
def each(&block) |
|
| 282 |
page_count.times do |n| |
|
| 283 |
yield self[n+1] |
|
| 284 |
end |
|
| 285 |
end |
|
| 286 |
|
|
| 287 |
# A class representing a single page in a paginator. |
|
| 288 |
class Page |
|
| 289 |
include Comparable |
|
| 290 |
|
|
| 291 |
# Creates a new Page for the given +paginator+ with the index |
|
| 292 |
# +number+. If +number+ is not in the range of valid page numbers or |
|
| 293 |
# is not a number at all, it defaults to 1. |
|
| 294 |
def initialize(paginator, number) |
|
| 295 |
@paginator = paginator |
|
| 296 |
@number = number.to_i |
|
| 297 |
@number = 1 unless @paginator.has_page_number? @number |
|
| 298 |
end |
|
| 299 |
attr_reader :paginator, :number |
|
| 300 |
alias to_i :number |
|
| 301 |
|
|
| 302 |
# Compares two Page objects and returns true when they represent the |
|
| 303 |
# same page (i.e., their paginators are the same and they have the |
|
| 304 |
# same page number). |
|
| 305 |
def ==(page) |
|
| 306 |
return false if page.nil? |
|
| 307 |
@paginator == page.paginator and |
|
| 308 |
@number == page.number |
|
| 309 |
end |
|
| 310 |
|
|
| 311 |
# Compares two Page objects and returns -1 if the left-hand page comes |
|
| 312 |
# before the right-hand page, 0 if the pages are equal, and 1 if the |
|
| 313 |
# left-hand page comes after the right-hand page. Raises ArgumentError |
|
| 314 |
# if the pages do not belong to the same Paginator object. |
|
| 315 |
def <=>(page) |
|
| 316 |
raise ArgumentError unless @paginator == page.paginator |
|
| 317 |
@number <=> page.number |
|
| 318 |
end |
|
| 319 |
|
|
| 320 |
# Returns the item offset for the first item in this page. |
|
| 321 |
def offset |
|
| 322 |
@paginator.items_per_page * (@number - 1) |
|
| 323 |
end |
|
| 324 |
|
|
| 325 |
# Returns the number of the first item displayed. |
|
| 326 |
def first_item |
|
| 327 |
offset + 1 |
|
| 328 |
end |
|
| 329 |
|
|
| 330 |
# Returns the number of the last item displayed. |
|
| 331 |
def last_item |
|
| 332 |
[@paginator.items_per_page * @number, @paginator.item_count].min |
|
| 333 |
end |
|
| 334 |
|
|
| 335 |
# Returns true if this page is the first page in the paginator. |
|
| 336 |
def first? |
|
| 337 |
self == @paginator.first |
|
| 338 |
end |
|
| 339 |
|
|
| 340 |
# Returns true if this page is the last page in the paginator. |
|
| 341 |
def last? |
|
| 342 |
self == @paginator.last |
|
| 343 |
end |
|
| 344 |
|
|
| 345 |
# Returns a new Page object representing the page just before this |
|
| 346 |
# page, or nil if this is the first page. |
|
| 347 |
def previous |
|
| 348 |
if first? then nil else @paginator[@number - 1] end |
|
| 349 |
end |
|
| 350 |
|
|
| 351 |
# Returns a new Page object representing the page just after this |
|
| 352 |
# page, or nil if this is the last page. |
|
| 353 |
def next |
|
| 354 |
if last? then nil else @paginator[@number + 1] end |
|
| 355 |
end |
|
| 356 |
|
|
| 357 |
# Returns a new Window object for this page with the specified |
|
| 358 |
# +padding+. |
|
| 359 |
def window(padding=2) |
|
| 360 |
Window.new(self, padding) |
|
| 361 |
end |
|
| 362 |
|
|
| 363 |
# Returns the limit/offset array for this page. |
|
| 364 |
def to_sql |
|
| 365 |
[@paginator.items_per_page, offset] |
|
| 366 |
end |
|
| 367 |
|
|
| 368 |
def to_param #:nodoc: |
|
| 369 |
@number.to_s |
|
| 370 |
end |
|
| 371 |
end |
|
| 372 |
|
|
| 373 |
# A class for representing ranges around a given page. |
|
| 374 |
class Window |
|
| 375 |
# Creates a new Window object for the given +page+ with the specified |
|
| 376 |
# +padding+. |
|
| 377 |
def initialize(page, padding=2) |
|
| 378 |
@paginator = page.paginator |
|
| 379 |
@page = page |
|
| 380 |
self.padding = padding |
|
| 381 |
end |
|
| 382 |
attr_reader :paginator, :page |
|
| 383 |
|
|
| 384 |
# Sets the window's padding (the number of pages on either side of the |
|
| 385 |
# window page). |
|
| 386 |
def padding=(padding) |
|
| 387 |
@padding = padding < 0 ? 0 : padding |
|
| 388 |
# Find the beginning and end pages of the window |
|
| 389 |
@first = @paginator.has_page_number?(@page.number - @padding) ? |
|
| 390 |
@paginator[@page.number - @padding] : @paginator.first |
|
| 391 |
@last = @paginator.has_page_number?(@page.number + @padding) ? |
|
| 392 |
@paginator[@page.number + @padding] : @paginator.last |
|
| 393 |
end |
|
| 394 |
attr_reader :padding, :first, :last |
|
| 395 |
|
|
| 396 |
# Returns an array of Page objects in the current window. |
|
| 397 |
def pages |
|
| 398 |
(@first.number..@last.number).to_a.collect! {|n| @paginator[n]}
|
|
| 399 |
end |
|
| 400 |
alias to_a :pages |
|
| 401 |
end |
|
| 402 |
end |
|
| 403 |
|
|
| 404 |
end |
|
| 405 |
end |
|
| lib/plugins/classic_pagination/lib/pagination_helper.rb | ||
|---|---|---|
| 1 |
module ActionView |
|
| 2 |
module Helpers |
|
| 3 |
# Provides methods for linking to ActionController::Pagination objects using a simple generator API. You can optionally |
|
| 4 |
# also build your links manually using ActionView::Helpers::AssetHelper#link_to like so: |
|
| 5 |
# |
|
| 6 |
# <%= link_to "Previous page", { :page => paginator.current.previous } if paginator.current.previous %>
|
|
| 7 |
# <%= link_to "Next page", { :page => paginator.current.next } if paginator.current.next %>
|
|
| 8 |
module PaginationHelper |
|
| 9 |
unless const_defined?(:DEFAULT_OPTIONS) |
|
| 10 |
DEFAULT_OPTIONS = {
|
|
| 11 |
:name => :page, |
|
| 12 |
:window_size => 2, |
|
| 13 |
:always_show_anchors => true, |
|
| 14 |
:link_to_current_page => false, |
|
| 15 |
:params => {}
|
|
| 16 |
} |
|
| 17 |
end |
|
| 18 |
|
|
| 19 |
# Creates a basic HTML link bar for the given +paginator+. Links will be created |
|
| 20 |
# for the next and/or previous page and for a number of other pages around the current |
|
| 21 |
# pages position. The +html_options+ hash is passed to +link_to+ when the links are created. |
|
| 22 |
# |
|
| 23 |
# ==== Options |
|
| 24 |
# <tt>:name</tt>:: the routing name for this paginator |
|
| 25 |
# (defaults to +page+) |
|
| 26 |
# <tt>:prefix</tt>:: prefix for pagination links |
|
| 27 |
# (i.e. Older Pages: 1 2 3 4) |
|
| 28 |
# <tt>:suffix</tt>:: suffix for pagination links |
|
| 29 |
# (i.e. 1 2 3 4 <- Older Pages) |
|
| 30 |
# <tt>:window_size</tt>:: the number of pages to show around |
|
| 31 |
# the current page (defaults to <tt>2</tt>) |
|
| 32 |
# <tt>:always_show_anchors</tt>:: whether or not the first and last |
|
| 33 |
# pages should always be shown |
|
| 34 |
# (defaults to +true+) |
|
| 35 |
# <tt>:link_to_current_page</tt>:: whether or not the current page |
|
| 36 |
# should be linked to (defaults to |
|
| 37 |
# +false+) |
|
| 38 |
# <tt>:params</tt>:: any additional routing parameters |
|
| 39 |
# for page URLs |
|
| 40 |
# |
|
| 41 |
# ==== Examples |
|
| 42 |
# # We'll assume we have a paginator setup in @person_pages... |
|
| 43 |
# |
|
| 44 |
# pagination_links(@person_pages) |
|
| 45 |
# # => 1 <a href="/?page=2/">2</a> <a href="/?page=3/">3</a> ... <a href="/?page=10/">10</a> |
|
| 46 |
# |
|
| 47 |
# pagination_links(@person_pages, :link_to_current_page => true) |
|
| 48 |
# # => <a href="/?page=1/">1</a> <a href="/?page=2/">2</a> <a href="/?page=3/">3</a> ... <a href="/?page=10/">10</a> |
|
| 49 |
# |
|
| 50 |
# pagination_links(@person_pages, :always_show_anchors => false) |
|
| 51 |
# # => 1 <a href="/?page=2/">2</a> <a href="/?page=3/">3</a> |
|
| 52 |
# |
|
| 53 |
# pagination_links(@person_pages, :window_size => 1) |
|
| 54 |
# # => 1 <a href="/?page=2/">2</a> ... <a href="/?page=10/">10</a> |
|
| 55 |
# |
|
| 56 |
# pagination_links(@person_pages, :params => { :viewer => "flash" })
|
|
| 57 |
# # => 1 <a href="/?page=2&viewer=flash/">2</a> <a href="/?page=3&viewer=flash/">3</a> ... |
|
| 58 |
# # <a href="/?page=10&viewer=flash/">10</a> |
|
| 59 |
def pagination_links(paginator, options={}, html_options={})
|
|
| 60 |
name = options[:name] || DEFAULT_OPTIONS[:name] |
|
| 61 |
params = (options[:params] || DEFAULT_OPTIONS[:params]).clone |
|
| 62 |
|
|
| 63 |
prefix = options[:prefix] || '' |
|
| 64 |
suffix = options[:suffix] || '' |
|
| 65 |
|
|
| 66 |
pagination_links_each(paginator, options, prefix, suffix) do |n| |
|
| 67 |
params[name] = n |
|
| 68 |
link_to(n.to_s, params, html_options) |
|
| 69 |
end |
|
| 70 |
end |
|
| 71 |
|
|
| 72 |
# Iterate through the pages of a given +paginator+, invoking a |
|
| 73 |
# block for each page number that needs to be rendered as a link. |
|
| 74 |
# |
|
| 75 |
# ==== Options |
|
| 76 |
# <tt>:window_size</tt>:: the number of pages to show around |
|
| 77 |
# the current page (defaults to +2+) |
|
| 78 |
# <tt>:always_show_anchors</tt>:: whether or not the first and last |
|
| 79 |
# pages should always be shown |
|
| 80 |
# (defaults to +true+) |
|
| 81 |
# <tt>:link_to_current_page</tt>:: whether or not the current page |
|
| 82 |
# should be linked to (defaults to |
|
| 83 |
# +false+) |
|
| 84 |
# |
|
| 85 |
# ==== Example |
|
| 86 |
# # Turn paginated links into an Ajax call |
|
| 87 |
# pagination_links_each(paginator, page_options) do |link| |
|
| 88 |
# options = { :url => {:action => 'list'}, :update => 'results' }
|
|
| 89 |
# html_options = { :href => url_for(:action => 'list') }
|
|
| 90 |
# |
|
| 91 |
# link_to_remote(link.to_s, options, html_options) |
|
| 92 |
# end |
|
| 93 |
def pagination_links_each(paginator, options, prefix = nil, suffix = nil) |
|
| 94 |
options = DEFAULT_OPTIONS.merge(options) |
|
| 95 |
link_to_current_page = options[:link_to_current_page] |
|
| 96 |
always_show_anchors = options[:always_show_anchors] |
|
| 97 |
|
|
| 98 |
current_page = paginator.current_page |
|
| 99 |
window_pages = current_page.window(options[:window_size]).pages |
|
| 100 |
return if window_pages.length <= 1 unless link_to_current_page |
|
| 101 |
|
|
| 102 |
first, last = paginator.first, paginator.last |
|
| 103 |
|
|
| 104 |
html = '' |
|
| 105 |
|
|
| 106 |
html << prefix if prefix |
|
| 107 |
|
|
| 108 |
if always_show_anchors and not (wp_first = window_pages[0]).first? |
|
| 109 |
html << yield(first.number) |
|
| 110 |
html << ' ... ' if wp_first.number - first.number > 1 |
|
| 111 |
html << ' ' |
|
| 112 |
end |
|
| 113 |
|
|
| 114 |
window_pages.each do |page| |
|
| 115 |
if current_page == page && !link_to_current_page |
|
| 116 |
html << page.number.to_s |
|
| 117 |
else |
|
| 118 |
html << yield(page.number) |
|
| 119 |
end |
|
| 120 |
html << ' ' |
|
| 121 |
end |
|
| 122 |
|
|
| 123 |
if always_show_anchors and not (wp_last = window_pages[-1]).last? |
|
| 124 |
html << ' ... ' if last.number - wp_last.number > 1 |
|
| 125 |
html << yield(last.number) |
|
| 126 |
end |
|
| 127 |
|
|
| 128 |
html << suffix if suffix |
|
| 129 |
|
|
| 130 |
html |
|
| 131 |
end |
|
| 132 |
|
|
| 133 |
end # PaginationHelper |
|
| 134 |
end # Helpers |
|
| 135 |
end # ActionView |
|
| lib/plugins/classic_pagination/test/fixtures/companies.yml | ||
|---|---|---|
| 1 |
thirty_seven_signals: |
|
| 2 |
id: 1 |
|
| 3 |
name: 37Signals |
|
| 4 |
rating: 4 |
|
| 5 |
|
|
| 6 |
TextDrive: |
|
| 7 |
id: 2 |
|
| 8 |
name: TextDrive |
|
| 9 |
rating: 4 |
|
| 10 |
|
|
| 11 |
PlanetArgon: |
|
| 12 |
id: 3 |
|
| 13 |
name: Planet Argon |
|
| 14 |
rating: 4 |
|
| 15 |
|
|
| 16 |
Google: |
|
| 17 |
id: 4 |
|
| 18 |
name: Google |
|
| 19 |
rating: 4 |
|
| 20 |
|
|
| 21 |
Ionist: |
|
| 22 |
id: 5 |
|
| 23 |
name: Ioni.st |
|
| 24 |
rating: 4 |
|
| lib/plugins/classic_pagination/test/fixtures/company.rb | ||
|---|---|---|
| 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 |
end |
|
| lib/plugins/classic_pagination/test/fixtures/developer.rb | ||
|---|---|---|
| 1 |
class Developer < ActiveRecord::Base |
|
| 2 |
has_and_belongs_to_many :projects |
|
| 3 |
end |
|
| 4 |
|
|
| 5 |
class DeVeLoPeR < ActiveRecord::Base |
|
| 6 |
self.table_name = "developers" |
|
| 7 |
end |
|
| lib/plugins/classic_pagination/test/fixtures/developers.yml | ||
|---|---|---|
| 1 |
david: |
|
| 2 |
id: 1 |
|
| 3 |
name: David |
|
| 4 |
salary: 80000 |
|
| 5 |
|
|
| 6 |
jamis: |
|
| 7 |
id: 2 |
|
| 8 |
name: Jamis |
|
| 9 |
salary: 150000 |
|
| 10 |
|
|
| 11 |
<% for digit in 3..10 %> |
|
| 12 |
dev_<%= digit %>: |
|
| 13 |
id: <%= digit %> |
|
| 14 |
name: fixture_<%= digit %> |
|
| 15 |
salary: 100000 |
|
| 16 |
<% end %> |
|
| 17 |
|
|
| 18 |
poor_jamis: |
|
| 19 |
id: 11 |
|
| 20 |
name: Jamis |
|
| 21 |
salary: 9000 |
|
| lib/plugins/classic_pagination/test/fixtures/developers_projects.yml | ||
|---|---|---|
| 1 |
david_action_controller: |
|
| 2 |
developer_id: 1 |
|
| 3 |
project_id: 2 |
|
| 4 |
joined_on: 2004-10-10 |
|
| 5 |
|
|
| 6 |
david_active_record: |
|
| 7 |
developer_id: 1 |
|
| 8 |
project_id: 1 |
|
| 9 |
joined_on: 2004-10-10 |
|
| 10 |
|
|
| 11 |
jamis_active_record: |
|
| 12 |
developer_id: 2 |
|
| 13 |
project_id: 1 |
|
| lib/plugins/classic_pagination/test/fixtures/project.rb | ||
|---|---|---|
| 1 |
class Project < ActiveRecord::Base |
|
| 2 |
has_and_belongs_to_many :developers, :uniq => true |
|
| 3 |
end |
|
| lib/plugins/classic_pagination/test/fixtures/projects.yml | ||
|---|---|---|
| 1 |
action_controller: |
|
| 2 |
id: 2 |
|
| 3 |
name: Active Controller |
|
| 4 |
|
|
| 5 |
active_record: |
|
| 6 |
id: 1 |
|
| 7 |
name: Active Record |
|
| lib/plugins/classic_pagination/test/fixtures/replies.yml | ||
|---|---|---|
| 1 |
witty_retort: |
|
| 2 |
id: 1 |
|
| 3 |
topic_id: 1 |
|
| 4 |
content: Birdman is better! |
|
| 5 |
created_at: <%= 6.hours.ago.to_s(:db) %> |
|
| 6 |
updated_at: nil |
|
| 7 |
|
|
| 8 |
another: |
|
| 9 |
id: 2 |
|
| 10 |
topic_id: 2 |
|
| 11 |
content: Nuh uh! |
|
| 12 |
created_at: <%= 1.hour.ago.to_s(:db) %> |
|
| 13 |
updated_at: nil |
|
| lib/plugins/classic_pagination/test/fixtures/reply.rb | ||
|---|---|---|
| 1 |
class Reply < ActiveRecord::Base |
|
| 2 |
belongs_to :topic, :include => [:replies] |
|
| 3 |
|
|
| 4 |
validates_presence_of :content |
|
| 5 |
end |
|
| lib/plugins/classic_pagination/test/fixtures/schema.sql | ||
|---|---|---|
| 1 |
CREATE TABLE 'companies' ( |
|
| 2 |
'id' INTEGER PRIMARY KEY NOT NULL, |
|
| 3 |
'name' TEXT DEFAULT NULL, |
|
| 4 |
'rating' INTEGER DEFAULT 1 |
|
| 5 |
); |
|
| 6 |
|
|
| 7 |
CREATE TABLE 'replies' ( |
|
| 8 |
'id' INTEGER PRIMARY KEY NOT NULL, |
|
| 9 |
'content' text, |
|
| 10 |
'created_at' datetime, |
|
| 11 |
'updated_at' datetime, |
|
| 12 |
'topic_id' integer |
|
| 13 |
); |
|
| 14 |
|
|
| 15 |
CREATE TABLE 'topics' ( |
|
| 16 |
'id' INTEGER PRIMARY KEY NOT NULL, |
|
| 17 |
'title' varchar(255), |
|
| 18 |
'subtitle' varchar(255), |
|
| 19 |
'content' text, |
|
| 20 |
'created_at' datetime, |
|
| 21 |
'updated_at' datetime |
|
| 22 |
); |
|
| 23 |
|
|
| 24 |
CREATE TABLE 'developers' ( |
|
| 25 |
'id' INTEGER PRIMARY KEY NOT NULL, |
|
| 26 |
'name' TEXT DEFAULT NULL, |
|
| 27 |
'salary' INTEGER DEFAULT 70000, |
|
| 28 |
'created_at' DATETIME DEFAULT NULL, |
|
| 29 |
'updated_at' DATETIME DEFAULT NULL |
|
| 30 |
); |
|
| 31 |
|
|
| 32 |
CREATE TABLE 'projects' ( |
|
| 33 |
'id' INTEGER PRIMARY KEY NOT NULL, |
|
| 34 |
'name' TEXT DEFAULT NULL |
|
| 35 |
); |
|
| 36 |
|
|
| 37 |
CREATE TABLE 'developers_projects' ( |
|
| 38 |
'developer_id' INTEGER NOT NULL, |
|
| 39 |
'project_id' INTEGER NOT NULL, |
|
| 40 |
'joined_on' DATE DEFAULT NULL, |
|
| 41 |
'access_level' INTEGER DEFAULT 1 |
|
| 42 |
); |
|
| lib/plugins/classic_pagination/test/fixtures/topic.rb | ||
|---|---|---|
| 1 |
class Topic < ActiveRecord::Base |
|
| 2 |
has_many :replies, :include => [:user], :dependent => :destroy |
|
| 3 |
end |
|
| lib/plugins/classic_pagination/test/fixtures/topics.yml | ||
|---|---|---|
| 1 |
futurama: |
|
| 2 |
id: 1 |
|
| 3 |
title: Isnt futurama awesome? |
|
| 4 |
subtitle: It really is, isnt it. |
|
| 5 |
content: I like futurama |
|
| 6 |
created_at: <%= 1.day.ago.to_s(:db) %> |
|
| 7 |
updated_at: |
|
| 8 |
|
|
| 9 |
harvey_birdman: |
|
| 10 |
id: 2 |
|
| 11 |
title: Harvey Birdman is the king of all men |
|
| 12 |
subtitle: yup |
|
| 13 |
content: It really is |
|
| 14 |
created_at: <%= 2.hours.ago.to_s(:db) %> |
|
| 15 |
updated_at: |
|
| 16 |
|
|
| 17 |
rails: |
|
| 18 |
id: 3 |
|
| 19 |
title: Rails is nice |
|
| 20 |
subtitle: It makes me happy |
|
| 21 |
content: except when I have to hack internals to fix pagination. even then really. |
|
| 22 |
created_at: <%= 20.minutes.ago.to_s(:db) %> |
|
| lib/plugins/classic_pagination/test/helper.rb | ||
|---|---|---|
| 1 |
require 'test/unit' |
|
| 2 |
|
|
| 3 |
unless defined?(ActiveRecord) |
|
| 4 |
plugin_root = File.join(File.dirname(__FILE__), '..') |
|
| 5 |
|
|
| 6 |
# first look for a symlink to a copy of the framework |
|
| 7 |
if framework_root = ["#{plugin_root}/rails", "#{plugin_root}/../../rails"].find { |p| File.directory? p }
|
|
| 8 |
puts "found framework root: #{framework_root}"
|
|
| 9 |
# this allows for a plugin to be tested outside an app |
|
| 10 |
$:.unshift "#{framework_root}/activesupport/lib", "#{framework_root}/activerecord/lib", "#{framework_root}/actionpack/lib"
|
|
| 11 |
else |
|
| 12 |
# is the plugin installed in an application? |
|
| 13 |
app_root = plugin_root + '/../../..' |
|
| 14 |
|
|
| 15 |
if File.directory? app_root + '/config' |
|
| 16 |
puts 'using config/boot.rb' |
|
| 17 |
ENV['RAILS_ENV'] = 'test' |
|
| 18 |
require File.expand_path(app_root + '/config/boot') |
|
| 19 |
else |
|
| 20 |
# simply use installed gems if available |
|
| 21 |
puts 'using rubygems' |
|
| 22 |
require 'rubygems' |
|
| 23 |
gem 'actionpack'; gem 'activerecord' |
|
| 24 |
end |
|
| 25 |
end |
|
| 26 |
|
|
| 27 |
%w(action_pack active_record action_controller active_record/fixtures action_controller/test_process).each {|f| require f}
|
|
| 28 |
|
|
| 29 |
Dependencies.load_paths.unshift "#{plugin_root}/lib"
|
|
| 30 |
end |
|
| 31 |
|
|
| 32 |
# Define the connector |
|
| 33 |
class ActiveRecordTestConnector |
|
| 34 |
cattr_accessor :able_to_connect |
|
| 35 |
cattr_accessor :connected |
|
| 36 |
|
|
| 37 |
# Set our defaults |
|
| 38 |
self.connected = false |
|
| 39 |
self.able_to_connect = true |
|
| 40 |
|
|
| 41 |
class << self |
|
| 42 |
def setup |
|
| 43 |
unless self.connected || !self.able_to_connect |
|
| 44 |
setup_connection |
|
| 45 |
load_schema |
|
| 46 |
require_fixture_models |
|
| 47 |
self.connected = true |
|
| 48 |
end |
|
| 49 |
rescue Exception => e # errors from ActiveRecord setup |
|
| 50 |
$stderr.puts "\nSkipping ActiveRecord assertion tests: #{e}"
|
|
| 51 |
#$stderr.puts " #{e.backtrace.join("\n ")}\n"
|
|
| 52 |
self.able_to_connect = false |
|
| 53 |
end |
|
| 54 |
|
|
| 55 |
private |
|
| 56 |
|
|
| 57 |
def setup_connection |
|
| 58 |
if Object.const_defined?(:ActiveRecord) |
|
| 59 |
defaults = { :database => ':memory:' }
|
|
| 60 |
begin |
|
| 61 |
options = defaults.merge :adapter => 'sqlite3', :timeout => 500 |
|
| 62 |
ActiveRecord::Base.establish_connection(options) |
|
| 63 |
ActiveRecord::Base.configurations = { 'sqlite3_ar_integration' => options }
|
|
| 64 |
ActiveRecord::Base.connection |
|
| 65 |
rescue Exception # errors from establishing a connection |
|
| 66 |
$stderr.puts 'SQLite 3 unavailable; trying SQLite 2.' |
|
| 67 |
options = defaults.merge :adapter => 'sqlite' |
|
| 68 |
ActiveRecord::Base.establish_connection(options) |
|
| 69 |
ActiveRecord::Base.configurations = { 'sqlite2_ar_integration' => options }
|
|
| 70 |
ActiveRecord::Base.connection |
|
| 71 |
end |
|
| 72 |
|
|
| 73 |
Object.send(:const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')) unless Object.const_defined?(:QUOTED_TYPE)
|
|
| 74 |
else |
|
| 75 |
raise "Can't setup connection since ActiveRecord isn't loaded." |
|
| 76 |
end |
|
| 77 |
end |
|
| 78 |
|
|
| 79 |
# Load actionpack sqlite tables |
|
| 80 |
def load_schema |
|
| 81 |
File.read(File.dirname(__FILE__) + "/fixtures/schema.sql").split(';').each do |sql|
|
|
| 82 |
ActiveRecord::Base.connection.execute(sql) unless sql.blank? |
|
| 83 |
end |
|
| 84 |
end |
|
| 85 |
|
|
| 86 |
def require_fixture_models |
|
| 87 |
Dir.glob(File.dirname(__FILE__) + "/fixtures/*.rb").each {|f| require f}
|
|
| 88 |
end |
|
| 89 |
end |
|
| 90 |
end |
|
| 91 |
|
|
| 92 |
# Test case for inheritance |
|
| 93 |
class ActiveRecordTestCase < Test::Unit::TestCase |
|
| 94 |
# Set our fixture path |
|
| 95 |
if ActiveRecordTestConnector.able_to_connect |
|
| 96 |
self.fixture_path = "#{File.dirname(__FILE__)}/fixtures/"
|
|
| 97 |
self.use_transactional_fixtures = false |
|
| 98 |
end |
|
| 99 |
|
|
| 100 |
def self.fixtures(*args) |
|
| 101 |
super if ActiveRecordTestConnector.connected |
|
| 102 |
end |
|
| 103 |
|
|
| 104 |
def run(*args) |
|
| 105 |
super if ActiveRecordTestConnector.connected |
|
| 106 |
end |
|
| 107 |
|
|
| 108 |
# Default so Test::Unit::TestCase doesn't complain |
|
| 109 |
def test_truth |
|
| 110 |
end |
|
| 111 |
end |
|
| 112 |
|
|
| 113 |
ActiveRecordTestConnector.setup |
|
| 114 |
ActionController::Routing::Routes.reload rescue nil |
|
| 115 |
ActionController::Routing::Routes.draw do |map| |
|
| 116 |
map.connect ':controller/:action/:id' |
|
| 117 |
end |
|
| lib/plugins/classic_pagination/test/pagination_helper_test.rb | ||
|---|---|---|
| 1 |
require File.dirname(__FILE__) + '/helper' |
|
| 2 |
require File.dirname(__FILE__) + '/../init' |
|
| 3 |
|
|
| 4 |
class PaginationHelperTest < Test::Unit::TestCase |
|
| 5 |
include ActionController::Pagination |
|
| 6 |
include ActionView::Helpers::PaginationHelper |
|
| 7 |
include ActionView::Helpers::UrlHelper |
|
| 8 |
include ActionView::Helpers::TagHelper |
|
| 9 |
|
|
| 10 |
def setup |
|
| 11 |
@controller = Class.new do |
|
| 12 |
attr_accessor :url, :request |
|
| 13 |
def url_for(options, *parameters_for_method_reference) |
|
| 14 |
url |
|
| 15 |
end |
|
| 16 |
end |
|
| 17 |
@controller = @controller.new |
|
| 18 |
@controller.url = "http://www.example.com" |
|
| 19 |
end |
|
| 20 |
|
|
| 21 |
def test_pagination_links |
|
| 22 |
total, per_page, page = 30, 10, 1 |
|
| 23 |
output = pagination_links Paginator.new(@controller, total, per_page, page) |
|
| 24 |
assert_equal "1 <a href=\"http://www.example.com\">2</a> <a href=\"http://www.example.com\">3</a> ", output |
|
| 25 |
end |
|
| 26 |
|
|
| 27 |
def test_pagination_links_with_prefix |
|
| 28 |
total, per_page, page = 30, 10, 1 |
|
| 29 |
output = pagination_links Paginator.new(@controller, total, per_page, page), :prefix => 'Newer ' |
|
| 30 |
assert_equal "Newer 1 <a href=\"http://www.example.com\">2</a> <a href=\"http://www.example.com\">3</a> ", output |
|
| 31 |
end |
|
| 32 |
|
|
| 33 |
def test_pagination_links_with_suffix |
|
| 34 |
total, per_page, page = 30, 10, 1 |
|
| 35 |
output = pagination_links Paginator.new(@controller, total, per_page, page), :suffix => 'Older' |
|
| 36 |
assert_equal "1 <a href=\"http://www.example.com\">2</a> <a href=\"http://www.example.com\">3</a> Older", output |
|
| 37 |
end |
|
| 38 |
end |
|
| lib/plugins/classic_pagination/test/pagination_test.rb | ||
|---|---|---|
| 1 |
require File.dirname(__FILE__) + '/helper' |
|
| 2 |
require File.dirname(__FILE__) + '/../init' |
|
| 3 |
|
|
| 4 |
class PaginationTest < ActiveRecordTestCase |
|
| 5 |
fixtures :topics, :replies, :developers, :projects, :developers_projects |
|
| 6 |
|
|
| 7 |
class PaginationController < ActionController::Base |
|
| 8 |
if respond_to? :view_paths= |
|
| 9 |
self.view_paths = [ "#{File.dirname(__FILE__)}/../fixtures/" ]
|
|
| 10 |
else |
|
| 11 |
self.template_root = [ "#{File.dirname(__FILE__)}/../fixtures/" ]
|
|
| 12 |
end |
|
| 13 |
|
|
| 14 |
def simple_paginate |
|
| 15 |
@topic_pages, @topics = paginate(:topics) |
|
| 16 |
render :nothing => true |
|
| 17 |
end |
|
| 18 |
|
|
| 19 |
def paginate_with_per_page |
|
| 20 |
@topic_pages, @topics = paginate(:topics, :per_page => 1) |
|
| 21 |
render :nothing => true |
|
| 22 |
end |
|
| 23 |
|
|
Also available in: Unified diff