Skip to content

Commit

Permalink
Make helpers work without count
Browse files Browse the repository at this point in the history
  • Loading branch information
Attila Horváth committed Apr 11, 2018
1 parent 62ec743 commit bd5c378
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 14 deletions.
7 changes: 0 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,13 +418,6 @@ Just add `.without_count` to your paginated object:
User.page(3).without_count
```
In your view file, you can only use simple helpers like the following instead of the full-featured `paginate` helper:
```erb
<%= link_to_prev_page @users, 'Previous Page' %>
<%= link_to_next_page @users, 'Next Page' %>
```
## Paginating a Generic Array object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ def total_count(column_name = :all, _options = nil) #:nodoc:
def without_count
extend ::Kaminari::PaginatableWithoutCount
end

def without_count?
false
end
end

# A module that makes AR::Relation paginatable without having to cast another SELECT COUNT query
Expand Down Expand Up @@ -87,8 +91,11 @@ def out_of_range?

# Force to raise an exception if #total_count is called explicitly.
def total_count
raise "This scope is marked as a non-count paginable scope and can't be used in combination " \
"with `#paginate' or `#page_entries_info'. Use #link_to_next_page or #link_to_previous_page instead."
raise 'This scope is marked as a non-count paginable scope.'
end

def without_count?
true
end
end
end
2 changes: 2 additions & 0 deletions kaminari-core/config/locales/kaminari.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ en:
other: "Displaying <b>all %{count}</b> %{entry_name}"
more_pages:
display_entries: "Displaying %{entry_name} <b>%{first}&nbsp;-&nbsp;%{last}</b> of <b>%{total}</b> in total"
without_count:
display_entries: "Displaying %{entry_name} <b>%{first}&nbsp;-&nbsp;%{last}</b>"
18 changes: 14 additions & 4 deletions kaminari-core/lib/kaminari/helpers/helper_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,13 @@ module HelperMethods
# * <tt>:template</tt> - Specify a custom template renderer for rendering the Paginator (receiver by default)
# * <tt>:ANY_OTHER_VALUES</tt> - Any other hash key & values would be directly passed into each tag as :locals value.
def paginate(scope, paginator_class: Kaminari::Helpers::Paginator, template: nil, **options)
options[:total_pages] ||= scope.total_pages
if scope.without_count?
options[:without_count] = true
options[:total_pages] = scope.last_page? ? scope.current_page : scope.current_page + 1
else
options[:total_pages] ||= scope.total_pages
end

options.reverse_merge! current_page: scope.current_page, per_page: scope.limit_value, remote: false

paginator = paginator_class.new (template || self), options
Expand Down Expand Up @@ -200,13 +206,17 @@ def page_entries_info(collection, entry_name: nil)
collection.entry_name(count: collection.size).downcase
end

if collection.total_pages < 2
t('helpers.page_entries_info.one_page.display_entries', entry_name: entry_name, count: collection.total_count)
if collection.first_page? && !collection.next_page
t('helpers.page_entries_info.one_page.display_entries', entry_name: entry_name, count: collection.size)
else
from = collection.offset_value + 1
to = collection.offset_value + collection.size

t('helpers.page_entries_info.more_pages.display_entries', entry_name: entry_name, first: from, last: to, total: collection.total_count)
if collection.without_count?
t('helpers.page_entries_info.without_count.display_entries', entry_name: entry_name, first: from, last: to)
else
t('helpers.page_entries_info.more_pages.display_entries', entry_name: entry_name, first: from, last: to, total: collection.total_count)
end
end.html_safe
end

Expand Down
6 changes: 5 additions & 1 deletion kaminari-core/lib/kaminari/helpers/paginator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ def initialize(template, window: nil, outer_window: Kaminari.config.outer_window
else
ActiveSupport::SafeBuffer.new
end

@render_without_count = true
end

# render given block as a view template
def render(&block)
instance_eval(&block) if @options[:total_pages] > 1
instance_eval(&block) if @options[:total_pages] > 1 || @options[:without_count]

# This allows for showing fall-back HTML when there's only one page:
#
Expand All @@ -49,6 +51,8 @@ def each_relevant_page
alias each_page each_relevant_page

def relevant_pages(options)
return [] if @options[:without_count]

left_window_plus_one = [*1..options[:left] + 1]
right_window_plus_one = [*options[:total_pages] - options[:right]..options[:total_pages]]
inside_window_plus_each_sides = [*options[:current_page] - options[:window] - 1..options[:current_page] + options[:window] + 1]
Expand Down
7 changes: 7 additions & 0 deletions kaminari-core/lib/kaminari/helpers/tags.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ def initialize(template, params: {}, param_name: nil, theme: nil, views_prefix:
@params = @params.with_indifferent_access
@params.except!(*PARAM_KEY_BLACKLIST)
@params.merge! params
@render_without_count = false
end

def to_s(locals = {}) #:nodoc:
return '' if @options[:without_count] && !@render_without_count

formats = (@template.respond_to?(:formats) ? @template.formats : Array(@template.params[:format])) + [:html]
@template.render partial: partial_path, locals: @options.merge(locals), formats: formats
end
Expand Down Expand Up @@ -128,6 +131,8 @@ def initialize(template, params: {}, param_name: nil, theme: nil, views_prefix:
end

super(template, params: params, param_name: param_name, theme: theme, views_prefix: views_prefix, **options)

@render_without_count = true
end

def page #:nodoc:
Expand All @@ -149,6 +154,8 @@ def initialize(template, params: {}, param_name: nil, theme: nil, views_prefix:
end

super(template, params: params, param_name: param_name, theme: theme, views_prefix: views_prefix, **options)

@render_without_count = true
end

def page #:nodoc:
Expand Down
113 changes: 113 additions & 0 deletions kaminari-core/test/helpers/action_view_extension_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ def to_s
assert_not_match(/Last/, html)
assert_not_match(/Next/, html)
end

test 'scope without count' do
users = User.page(7).without_count

html = view.paginate users, params: {controller: 'users', action: 'index'}
assert_match(/<a [^>]*>&lsaquo; Prev<\/a>/, html)
assert_match(/<a [^>]*>Next &rsaquo;<\/a>/, html)
assert_not_match(/First/, html)
assert_not_match(/Last/, html)
end
end

sub_test_case '#link_to_previous_page' do
Expand Down Expand Up @@ -472,6 +482,109 @@ def total_count
end
end

sub_test_case 'on a scope without count' do
sub_test_case 'having no entries' do
test 'with default entry name' do
users = User.page(1).per(25).without_count
assert_equal 'No users found', view.page_entries_info(users)
end

test 'setting the entry name option to "member"' do
users = User.page(1).per(25).without_count
assert_equal 'No members found', view.page_entries_info(users, entry_name: 'member')
end
end

sub_test_case 'having 1 entry' do
setup do
User.create! name: 'user1'
end

test 'with default entry name' do
users = User.page(1).per(25).without_count
assert_equal 'Displaying <b>1</b> user', view.page_entries_info(users)
end

test 'setting the entry name option to "member"' do
users = User.page(1).per(25).without_count
assert_equal 'Displaying <b>1</b> member', view.page_entries_info(users, entry_name: 'member')
end
end

sub_test_case 'having more than 1 but less than a page of entries' do
setup do
10.times {|i| User.create! name: "user#{i}"}
end

test 'with default entry name' do
users = User.page(1).per(25).without_count
assert_equal 'Displaying <b>all 10</b> users', view.page_entries_info(users)
end

test 'setting the entry name option to "member"' do
users = User.page(1).per(25).without_count
assert_equal 'Displaying <b>all 10</b> members', view.page_entries_info(users, entry_name: 'member')
end
end

sub_test_case 'having more than one page of entries' do
setup do
50.times {|i| User.create! name: "user#{i}"}
end

sub_test_case 'the first page' do
test 'with default entry name' do
users = User.page(1).per(25).without_count
assert_equal 'Displaying users <b>1&nbsp;-&nbsp;25</b>', view.page_entries_info(users)
end

test 'setting the entry name option to "member"' do
users = User.page(1).per(25).without_count
assert_equal 'Displaying members <b>1&nbsp;-&nbsp;25</b>', view.page_entries_info(users, entry_name: 'member')
end
end

sub_test_case 'the next page' do
test 'with default entry name' do
users = User.page(2).per(25).without_count
assert_equal 'Displaying users <b>26&nbsp;-&nbsp;50</b>', view.page_entries_info(users)
end

test 'setting the entry name option to "member"' do
users = User.page(2).per(25).without_count
assert_equal 'Displaying members <b>26&nbsp;-&nbsp;50</b>', view.page_entries_info(users, entry_name: 'member')
end
end

sub_test_case 'the last page' do
test 'with default entry name' do
begin
User.max_pages 4
users = User.page(4).per(10).without_count

assert_equal 'Displaying users <b>31&nbsp;-&nbsp;40</b>', view.page_entries_info(users)
ensure
User.max_pages nil
end
end
end

test 'it accepts a decorated object' do
page_info_presenter = Class.new(SimpleDelegator) do
include ActionView::Helpers::NumberHelper

def total_count
number_with_delimiter(1_000)
end
end

users = page_info_presenter.new(User.page(1).per(25).without_count)

assert_equal 'Displaying users <b>1&nbsp;-&nbsp;25</b>', view.page_entries_info(users)
end
end
end

test 'on a PaginatableArray' do
numbers = Kaminari.paginate_array(%w{one two three}).page(1)

Expand Down

0 comments on commit bd5c378

Please sign in to comment.