Skip to content

Commit

Permalink
Update FacetPaginator to support kaminari 0.16.0. Fixes #928
Browse files Browse the repository at this point in the history
  • Loading branch information
jcoyne committed Jun 10, 2014
1 parent 2fed27a commit 8157ebb
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 89 deletions.
2 changes: 1 addition & 1 deletion app/views/catalog/_facet_limit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</li>
<% end %>
<% if paginator.has_next? and params[:action] != "facet" %>
<% unless paginator.last_page? || params[:action] == "facet" %>
<li class="more_facets_link"><%= link_to(t('blacklight.search.facets.more'), params.merge(:id => solr_field, :action=>"facet", :page => nil), :class => "more_facets_link") %></li>
<% end %>

Expand Down
81 changes: 51 additions & 30 deletions lib/blacklight/solr/facet_paginator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ module Blacklight::Solr
# so we cannot know how many "pages" there are.
#
class FacetPaginator
extend Deprecation

self.deprecation_horizon = 'blacklight version 6.0.0'

# What request keys will we use for the parameters need. Need to
# make sure they do NOT conflict with catalog/index request params,
# and need to make them accessible in a list so we can easily
Expand All @@ -21,7 +25,7 @@ class FacetPaginator
class << self; attr_accessor :request_keys end # create a class method
def request_keys ; self.class.request_keys ; end # shortcut

attr_reader :total, :items, :offset, :limit, :sort
attr_reader :total_count, :items, :offset, :limit, :sort

# all_facet_values is a list of facet value objects returned by solr,
# asking solr for n+1 facet values.
Expand All @@ -33,54 +37,71 @@ def request_keys ; self.class.request_keys ; end # shortcut
def initialize(all_facet_values, arguments)
# to_s.to_i will conveniently default to 0 if nil
@offset = arguments[:offset].to_s.to_i
@limit = arguments[:limit].to_s.to_i if arguments[:limit]
@limit = arguments[:limit].to_s.to_i
# count is solr's default
@sort = arguments[:sort] || "count"

total = all_facet_values.size
if (@limit)
@items = all_facet_values.slice(0, @limit)
@has_next = total > @limit
@has_previous = @offset > 0
else # nil limit
@items = all_facet_values
@has_next = false
@has_previous = false
end
@total_count = all_facet_values.size
@items = items_for_limit(all_facet_values)
end

def prev_page
current_page - 1 unless first_page?
end

def current_page
1 + @offset/@limit
if limit == 0 #check for divide by zero
1
else
@offset/limit + 1
end
end

def next_page
current_page + 1 unless last_page?
end

#@deprecated
def has_next?
@has_next
!last_page?
end
deprecation_deprecate :has_next?

#@deprecated
def has_previous?
@has_previous
!first_page?
end
deprecation_deprecate :has_next?

def last_page?
!has_next?
current_page >= total_pages
end

def first_page?
!has_previous?
current_page == 1
end

def total_pages
if limit == 0 #check for divide by zero
1
else
(total_count.to_f / limit).ceil
end
end

# Pass in a desired solr facet solr key ('count' or 'index', see
# http://wiki.apache.org/solr/SimpleFacetParameters#facet.limit
# under facet.sort ), and your current request params.
# Get back params suitable to passing to an ActionHelper method for
# creating a url, to resort by that method.
def params_for_resort_url(sort_method, params)
# When resorting, we've got to reset the offset to start at beginning,
# no way to make it make sense otherwise.
return params.merge(request_keys[:sort] => sort_method, request_keys[:page] => nil)
end

# Pass in a desired solr facet solr key ('count' or 'index', see
# http://wiki.apache.org/solr/SimpleFacetParameters#facet.limit
# under facet.sort ), and your current request params.
# Get back params suitable to passing to an ActionHelper method for
# creating a url, to resort by that method.
def params_for_resort_url(sort_method, params)
# When resorting, we've got to reset the offset to start at beginning,
# no way to make it make sense otherwise.
params.merge(request_keys[:sort] => sort_method, request_keys[:page] => nil)
end

private
def items_for_limit(values)
limit ? values.slice(offset, limit) : values
end
end

end
102 changes: 44 additions & 58 deletions spec/lib/blacklight/facet_paginator_spec.rb
Original file line number Diff line number Diff line change
@@ -1,75 +1,61 @@
require 'spec_helper'
require 'yaml'

describe 'Blacklight::Solr::FacetPaginator' do
before(:all) do
require 'yaml'
@seven_facet_values = YAML::load("--- \n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 792\n value: Book\n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 65\n value: Musical Score\n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 58\n value: Serial\n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 48\n value: Musical Recording\n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 37\n value: Microform\n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 27\n value: Thesis\n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 0\n value: \n")
@six_facet_values = @seven_facet_values.slice(1,6)
@limit = 6

@sort_key = Blacklight::Solr::FacetPaginator.request_keys[:sort]
@page_key = Blacklight::Solr::FacetPaginator.request_keys[:page]
end
context 'when there are limit+1 results' do
before(:each) do
@paginator = Blacklight::Solr::FacetPaginator.new(@seven_facet_values, :limit => 6)
end
it 'should have next' do
expect(@paginator).to have_next
end
let(:seven_facet_values) { YAML::load("--- \n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 792\n value: Book\n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 65\n value: Musical Score\n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 58\n value: Serial\n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 48\n value: Musical Recording\n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 37\n value: Microform\n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 27\n value: Thesis\n- !ruby/object:Blacklight::SolrResponse::Facets::FacetItem \n hits: 0\n value: \n") }
let(:six_facet_values) { seven_facet_values.slice(1,6) }
let(:limit) { 6 }

context 'on the first page of two pages' do
subject { Blacklight::Solr::FacetPaginator.new(seven_facet_values, limit: limit) }
it { should be_first_page }
it { should_not be_last_page }
its(:current_page) { should eq 1 }
its(:prev_page) { should be_nil }
its(:next_page) { should eq 2 }
it 'should limit items to limit, if limit is smaller than items.length' do
expect(subject.items.size).to eq 6
end
end
it 'should not have next when there are fewer results' do
paginator = Blacklight::Solr::FacetPaginator.new(@six_facet_values, :offset => 0, :limit => @limit)

expect(paginator).not_to have_next
end
context 'when offset is greater than 0' do
before(:each) do
@offset = 100
@paginator = Blacklight::Solr::FacetPaginator.new(@seven_facet_values, :offset => @offset, :limit => @limit)
end

it 'should have previous' do
expect(@paginator).to have_previous
context 'on the last page of two pages' do
subject { Blacklight::Solr::FacetPaginator.new(seven_facet_values, offset: 6, limit: limit) }
it { should_not be_first_page }
it { should be_last_page }
its(:current_page) { should eq 2 }
its(:prev_page) { should eq 1 }
its(:next_page) { should be_nil }
it 'should return all items when limit is greater than items.length' do
expect(subject.items.size).to eq 1
end

end
it 'should not have previous when offset is 0' do
paginator = Blacklight::Solr::FacetPaginator.new(@seven_facet_values, :offset => 0, :limit => @limit)

expect(paginator).not_to have_previous
context 'on the first page of one page' do
subject { Blacklight::Solr::FacetPaginator.new(six_facet_values, offset: 0, limit: limit) }
it { should be_first_page }
it { should be_last_page }
end
it 'should know a manually set sort, and produce proper sort url' do
paginator = Blacklight::Solr::FacetPaginator.new(@seven_facet_values, :offset => 100, :limit => @limit, :sort => 'index')

expect(paginator.sort).to eq 'index'

click_params = paginator.params_for_resort_url('count', {})
describe "params_for_resort_url" do
let(:sort_key) { Blacklight::Solr::FacetPaginator.request_keys[:sort] }
let(:page_key) { Blacklight::Solr::FacetPaginator.request_keys[:page] }
let(:paginator) { Blacklight::Solr::FacetPaginator.new(seven_facet_values, offset: 100, limit: limit, sort: 'index') }

expect(click_params[ @sort_key ]).to eq 'count'
expect(click_params[ @page_key ]).to be_nil
end
it 'should limit items to limit, if limit is smaller than items.length' do
paginator = Blacklight::Solr::FacetPaginator.new(@seven_facet_values, :offset => 100, :limit => 6, :sort => 'index')
expect(paginator.items).to have(6).items
end
it 'should return all items when limit is greater than items.length' do
paginator = Blacklight::Solr::FacetPaginator.new(@six_facet_values, :offset => 100, :limit => 6, :sort => 'index')
expect(paginator.items).to have(6).items
end
describe "for a nil :limit" do
before(:all) do
@paginator = Blacklight::Solr::FacetPaginator.new(@seven_facet_values, :offset => 100, :limit => nil, :sort => 'index')
end
it 'should return all items' do
expect(@paginator.items).to eq @seven_facet_values
end
it 'should not has_next?' do
expect(@paginator).not_to have_next
it 'should know a manually set sort, and produce proper sort url' do
expect(paginator.sort).to eq 'index'

click_params = paginator.params_for_resort_url('count', {})

expect(click_params[ sort_key ]).to eq 'count'
expect(click_params[ page_key ]).to be_nil
end
it 'should not has_previous?' do
expect(@paginator).not_to have_previous
end

context "for a nil :limit" do
subject { Blacklight::Solr::FacetPaginator.new(seven_facet_values, offset: 0, limit: nil, sort: 'index') }
it "should have items" do
expect(subject.items).to be_empty
end
end

Expand Down

0 comments on commit 8157ebb

Please sign in to comment.