Git Product home page Git Product logo

kaminari's Introduction

Kaminari Build Status Code Climate

A Scope & Engine based, clean, powerful, customizable and sophisticated paginator for modern web app frameworks and ORMs

Features

Clean

Does not globally pollute Array, Hash, Object or AR::Base.

Easy to Use

Just bundle the gem, then your models are ready to be paginated. No configuration required. Don't have to define anything in your models or helpers.

Simple Scope-based API

Everything is method chainable with less "Hasheritis". You know, that's the modern Rails way. No special collection class or anything for the paginated values, instead using a general AR::Relation instance. So, of course you can chain any other conditions before or after the paginator scope.

Customizable Engine-based I18n-aware Helpers

As the whole pagination helper is basically just a collection of links and non-links, Kaminari renders each of them through its own partial template inside the Engine. So, you can easily modify their behaviour, style or whatever by overriding partial templates.

ORM & Template Engine Agnostic

Kaminari supports multiple ORMs (ActiveRecord, DataMapper, Mongoid, MongoMapper), multiple web frameworks (Rails, Sinatra, Grape), and multiple template engines (ERB, Haml, Slim).

Modern

The pagination helper outputs the HTML5 <nav> tag by default. Plus, the helper supports Rails unobtrusive Ajax.

Supported Versions

  • Ruby 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, 3.3

  • Rails 4.1, 4.2, 5.0, 5.1, 5.2, 6.0, 6.1, 7.0, 7.1

  • Sinatra 1.4, 2.0

  • Haml 3+

  • Mongoid 3+

  • MongoMapper 0.9+

  • DataMapper 1.1.0+

Installation

To install kaminari on the default Rails stack, just put this line in your Gemfile:

gem 'kaminari'

Then bundle:

% bundle

If you're building non-Rails or non-ActiveRecord app and want the pagination feature on it, please take a look at Other Framework/Library Support section.

Query Basics

The page Scope

To fetch the 7th page of users (default per_page is 25)

User.page(7)

Note: pagination starts at page 1, not at page 0 (page(0) will return the same results as page(1)).

Kaminari does not add an order to queries. To avoid surprises, you should generally include an order in paginated queries. For example:

User.order(:name).page(7)

You can get page numbers or page conditions by using below methods.

User.count                     #=> 1000
User.page(1).limit_value       #=> 20
User.page(1).total_pages       #=> 50
User.page(1).current_page      #=> 1
User.page(1).next_page         #=> 2
User.page(2).prev_page         #=> 1
User.page(1).first_page?       #=> true
User.page(50).last_page?       #=> true
User.page(100).out_of_range?   #=> true

The per Scope

To show a lot more users per each page (change the per value)

User.order(:name).page(7).per(50)

Note that the per scope is not directly defined on the models but is just a method defined on the page scope. This is absolutely reasonable because you will never actually use per without specifying the page number.

Keep in mind that per internally utilizes limit and so it will override any limit that was set previously. And if you want to get the size for all request records you can use total_count method:

User.count                     #=> 1000
a = User.limit(5); a.count     #=> 5
a.page(1).per(20).size         #=> 20
a.page(1).per(20).total_count  #=> 1000

The padding Scope

Occasionally you need to pad a number of records that is not a multiple of the page size.

User.order(:name).page(7).per(50).padding(3)

Note that the padding scope also is not directly defined on the models.

Unscoping

If for some reason you need to unscope page and per methods you can call except(:limit, :offset)

users = User.order(:name).page(7).per(50)
unpaged_users = users.except(:limit, :offset) # unpaged_users will not use the kaminari scopes

Configuring Kaminari

General Configuration Options

You can configure the following default values by overriding these values using Kaminari.configure method.

default_per_page      # 25 by default
max_per_page          # nil by default
max_pages             # nil by default
window                # 4 by default
outer_window          # 0 by default
left                  # 0 by default
right                 # 0 by default
page_method_name      # :page by default
param_name            # :page by default
params_on_first_page  # false by default

There's a handy generator that generates the default configuration file into config/initializers directory. Run the following generator command, then edit the generated file.

% rails g kaminari:config

Changing page_method_name

You can change the method name page to bonzo or plant or whatever you like, in order to play nice with existing page method or association or scope or any other plugin that defines page method on your models.

Configuring Default per_page Value for Each Model by paginates_per

You can specify default per_page value per each model using the following declarative DSL.

class User < ActiveRecord::Base
  paginates_per 50
end

Configuring Max per_page Value for Each Model by max_paginates_per

You can specify max per_page value per each model using the following declarative DSL. If the variable that specified via per scope is more than this variable, max_paginates_per is used instead of it. Default value is nil, which means you are not imposing any max per_page value.

class User < ActiveRecord::Base
  max_paginates_per 100
end

Configuring max_pages Value for Each Model by max_pages

You can specify max_pages value per each model using the following declarative DSL. This value restricts the total number of pages that can be returned. Useful for setting limits on large collections.

class User < ActiveRecord::Base
  max_pages 100
end

Configuring params_on_first_page when using ransack_memory

If you are using the ransack_memory gem and experience problems navigating back to the previous or first page, set the params_on_first_page setting to true.

Controllers

The Page Parameter Is in params[:page]

Typically, your controller code will look like this:

@users = User.order(:name).page params[:page]

Views

The Same Old Helper Method

Just call the paginate helper:

<%= paginate @users %>

This will render several ?page=N pagination links surrounded by an HTML5 <nav> tag.

Helpers

The paginate Helper Method

<%= paginate @users %>

This would output several pagination links such as « First ‹ Prev ... 2 3 4 5 6 7 8 9 10 ... Next › Last ».

Specifying the "inner window" Size (4 by default)

<%= paginate @users, window: 2 %>

This would output something like ... 5 6 7 8 9 ... when 7 is the current page.

Specifying the "outer window" Size (0 by default)

<%= paginate @users, outer_window: 3 %>

This would output something like 1 2 3 ...(snip)... 18 19 20 while having 20 pages in total.

Outer Window Can Be Separately Specified by left, right (0 by default)

<%= paginate @users, left: 1, right: 3 %>

This would output something like 1 ...(snip)... 18 19 20 while having 20 pages in total.

Changing the Parameter Name (:param_name) for the Links

<%= paginate @users, param_name: :pagina %>

This would modify the query parameter name on each links.

Extra Parameters (:params) for the Links

<%= paginate @users, params: {controller: 'foo', action: 'bar', format: :turbo_stream} %>

This would modify each link's url_option. :controller and :action might be the keys in common.

Ajax Links (crazy simple, but works perfectly!)

<%= paginate @users, remote: true %>

This would add data-remote="true" to all the links inside.

Specifying an Alternative Views Directory (default is kaminari/)

<%= paginate @users, views_prefix: 'templates' %>

This would search for partials in app/views/templates/kaminari. This option makes it easier to do things like A/B testing pagination templates/themes, using new/old templates at the same time as well as better integration with other gems such as cells.

The link_to_next_page and link_to_previous_page (aliased to link_to_prev_page) Helper Methods

<%= link_to_next_page @items, 'Next Page' %>

This simply renders a link to the next page. This would be helpful for creating a Twitter-like pagination feature.

The helper methods support a params option to further specify the link. If format needs to be set, include it in the params hash.

<%= link_to_next_page @items, 'Next Page', params: {controller: 'foo', action: 'bar', format: :turbo_stream} %>

The page_entries_info Helper Method

<%= page_entries_info @posts %>

This renders a helpful message with numbers of displayed vs. total entries.

By default, the message will use the humanized class name of objects in collection: for instance, "project types" for ProjectType models. The namespace will be cut out and only the last name will be used. Override this with the :entry_name parameter:

<%= page_entries_info @posts, entry_name: 'item' %>
#=> Displaying items 6 - 10 of 26 in total

The rel_next_prev_link_tags Helper Method

<%= rel_next_prev_link_tags @users %>

This renders the rel next and prev link tags for the head.

The path_to_next_page Helper Method

<%= path_to_next_page @users %>

This returns the server relative path to the next page.

The path_to_prev_page Helper Method

<%= path_to_prev_page @users %>

This returns the server relative path to the previous page.

I18n and Labels

The default labels for 'first', 'last', 'previous', '...' and 'next' are stored in the I18n yaml inside the engine, and rendered through I18n API. You can switch the label value per I18n.locale for your internationalized application. Keys and the default values are the following. You can override them by adding to a YAML file in your Rails.root/config/locales directory.

en:
  views:
    pagination:
      first: "&laquo; First"
      last: "Last &raquo;"
      previous: "&lsaquo; Prev"
      next: "Next &rsaquo;"
      truncate: "&hellip;"
  helpers:
    page_entries_info:
      one_page:
        display_entries:
          zero: "No %{entry_name} found"
          one: "Displaying <b>1</b> %{entry_name}"
          other: "Displaying <b>all %{count}</b> %{entry_name}"
      more_pages:
        display_entries: "Displaying %{entry_name} <b>%{first}–%{last}</b> of <b>%{total}</b> in total"

If you use non-English localization see i18n rules for changing one_page:display_entries block.

Customizing the Pagination Helper

Kaminari includes a handy template generator.

To Edit Your Paginator

Run the generator first,

% rails g kaminari:views default

then edit the partials in your app's app/views/kaminari/ directory.

For Haml/Slim Users

You can use the html2haml gem or the html2slim gem to convert erb templates. The kaminari gem will automatically pick up haml/slim templates if you place them in app/views/kaminari/.

Multiple Templates

In case you need different templates for your paginator (for example public and admin), you can pass --views-prefix directory like this:

% rails g kaminari:views default --views-prefix admin

that will generate partials in app/views/admin/kaminari/ directory.

Themes

The generator has the ability to fetch several sample template themes from the external repository (https://github.com/amatsuda/kaminari_themes) in addition to the bundled "default" one, which will help you creating a nice looking paginator.

% rails g kaminari:views THEME

To see the full list of available themes, take a look at the themes repository, or just hit the generator without specifying THEME argument.

% rails g kaminari:views

Multiple Themes

To utilize multiple themes from within a single application, create a directory within the app/views/kaminari/ and move your custom template files into that directory.

% rails g kaminari:views default (skip if you have existing kaminari views)
% cd app/views/kaminari
% mkdir my_custom_theme
% cp _*.html.* my_custom_theme/

Next, reference that directory when calling the paginate method:

<%= paginate @users, theme: 'my_custom_theme' %>

Customize away!

Note: if the theme isn't present or none is specified, kaminari will default back to the views included within the gem.

Paginating Without Issuing SELECT COUNT Query

Generally the paginator needs to know the total number of records to display the links, but sometimes we don't need the total number of records and just need the "previous page" and "next page" links. For such use case, Kaminari provides without_count mode that creates a paginatable collection without counting the number of all records. This may be helpful when you're dealing with a very large dataset because counting on a big table tends to become slow on RDBMS.

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:

<%= link_to_prev_page @users, 'Previous Page' %>
<%= link_to_next_page @users, 'Next Page' %>

Paginating a Generic Array object

Kaminari provides an Array wrapper class that adapts a generic Array object to the paginate view helper. However, the paginate helper doesn't automatically handle your Array object (this is intentional and by design). Kaminari::paginate_array method converts your Array object into a paginatable Array that accepts page method.

@paginatable_array = Kaminari.paginate_array(my_array_object).page(params[:page]).per(10)

You can specify the total_count value through options Hash. This would be helpful when handling an Array-ish object that has a different count value from actual count such as RSolr search result or when you need to generate a custom pagination. For example:

@paginatable_array = Kaminari.paginate_array([], total_count: 145).page(params[:page]).per(10)

or, in the case of using an external API to source the page of data:

page_size = 10
one_page = get_page_of_data params[:page], page_size
@paginatable_array = Kaminari.paginate_array(one_page.data, total_count: one_page.total_count).page(params[:page]).per(page_size)

Creating Friendly URLs and Caching

Because of the page parameter and Rails routing, you can easily generate SEO and user-friendly URLs. For any resource you'd like to paginate, just add the following to your routes.rb:

resources :my_resources do
  get 'page/:page', action: :index, on: :collection
end

If you are using Rails 4 or later, you can simplify route definitions by using concern:

concern :paginatable do
  get '(page/:page)', action: :index, on: :collection, as: ''
end

resources :my_resources, concerns: :paginatable

This will create URLs like /my_resources/page/33 instead of /my_resources?page=33. This is now a friendly URL, but it also has other added benefits...

Because the page parameter is now a URL segment, we can leverage on Rails page caching!

NOTE: In this example, I've pointed the route to my :index action. You may have defined a custom pagination action in your controller - you should point action: :your_custom_action instead.

Other Framework/Library Support

The kaminari gem

Technically, the kaminari gem consists of 3 individual components:

kaminari-core: the core pagination logic
kaminari-activerecord: Active Record adapter
kaminari-actionview: Action View adapter

So, bundling gem 'kaminari' is equivalent to the following 2 lines (kaminari-core is referenced from the adapters):

gem 'kaminari-activerecord'
gem 'kaminari-actionview'

For Other ORM Users

If you want to use other supported ORMs instead of ActiveRecord, for example Mongoid, bundle its adapter instead of kaminari-activerecord.

gem 'kaminari-mongoid'
gem 'kaminari-actionview'

Kaminari currently provides adapters for the following ORMs:

For Other Web Framework Users

If you want to use other web frameworks instead of Rails + Action View, for example Sinatra, bundle its adapter instead of kaminari-actionview.

gem 'kaminari-activerecord'
gem 'kaminari-sinatra'

Kaminari currently provides adapters for the following web frameworks:

For More Information

Check out Kaminari recipes on the GitHub Wiki for more advanced tips and techniques. https://github.com/kaminari/kaminari/wiki/Kaminari-recipes

Questions, Feedback

Feel free to message me on Github (amatsuda) or Twitter (@a_matsuda) ☇☇☇ :)

Contributing to Kaminari

Fork, fix, then send a pull request.

To run the test suite locally against all supported frameworks:

% bundle install
% rake test:all

To target the test suite against one framework:

% rake test:active_record_50

You can find a list of supported test tasks by running rake -T. You may also find it useful to run a specific test for a specific framework. To do so, you'll have to first make sure you have bundled everything for that configuration, then you can run the specific test:

% BUNDLE_GEMFILE='gemfiles/active_record_50.gemfile' bundle install
% BUNDLE_GEMFILE='gemfiles/active_record_50.gemfile' TEST=kaminari-core/test/requests/navigation_test.rb bundle exec rake test

Copyright

Copyright (c) 2011- Akira Matsuda. See MIT-LICENSE for further details.

kaminari's People

Contributors

5t111111 avatar ajrkerr avatar amatsuda avatar antstorm avatar apotonick avatar bricker avatar dblock avatar denysonique avatar eitoball avatar heel avatar hsbt avatar hundred avatar jdufresne avatar juno avatar l15n avatar linuus avatar mishina2228 avatar neilang avatar petergoldstein avatar phylor avatar plribeiro3000 avatar ragmaanir avatar rrrene avatar sachin21 avatar timgremore avatar udzura avatar wbyoung avatar xiaohui-zhangxh avatar yui-knk avatar yuki24 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kaminari's Issues

size is not accurate

Entry.accepted.size # => 4
Entry.accepted.page(1).per(2).size # => 4

The returned array only has 2 elements as you would except, but size reports 4.

This may not be a kaminari issue, since you are just delegating to ActiveRecord scopes.

Subclassed models generate scope override warnings

In Rails 3.0.5, any subclassed model that is loaded, ever, will produce the following warning in the Rails server log:

Creating scope :page. Overwriting existing method <model_name>.page.

I believe a proper fix here would be to have Kaminari make sure that it has not created the page (and others?) scope before doing so. This way, when a subclass initializes it would not recreate/override the scope that was already defined on the parent class. It's not necessary and it produces this warning message (see: https://rails.lighthouseapp.com/projects/8994/tickets/4083-patch-named-scopes-should-be-allowed-to-overwrite-an-existing-method).

If you'd like to see a sample app where this happens I can upload one to github.

Thanks!

Should have real first/last page links, and these should be used by default instead of outer window

I was looking into some more details of will_paginate's behavior related to :outer_window, and it occurs to me that there's a more basic problem with the current versions of both will_paginate and kaminari: neither seems to properly support "first page" and "last page" links in the default configuration.

Will_paginate-style outer windows are in fact uncommon in the wild, and they only really exist to cover the lack of a proper "first" and "last". In this light, will_paginate's definition of the outer windows as "extra pages around the first and last pages" is more understandable. But, it's also an opportunity for kaminari to do things right by reflecting the predominant styles used on the web in its defaults.

Take a look at this nice set of example paginators from Smashing Magazine (via the will_paginate docs). Although the specific elements that are present varies, the order of presentation is invariant:

[first] [previous] 1 2 ... 5 6 [7] 8 9 ... 12 13 [next] [last]

Of particular note, a "first page" link, if present, should always precede the "previous page" link, and vice-versa for last/next. The outer windows cannot properly substitute for these links because by definition they appear interior to "previous" and "next". Furthermore, "first" and "last" links should appear in addition to the page numbers of the first and last pages if you are using an outer window, as shown above. (If you were on page 12, "13", "next", and "last" might all point to the same page; that's perfectly fine.)

A complete paginator specification requires answers to all of the following questions:

  1. Should a "first page" link be displayed?
  2. If so, should it be omitted when you are on the first page (vs. displayed but disabled)?
  3. Should a "previous page" link be displayed?
  4. If so, should it be omitted when you are on the first page (vs. displayed but disabled)?
  5. Should the first N pages always be displayed? How many?
  6. How many pages surrounding the current page should be displayed?
  7. Should the last N pages always be displayed? How many?
  8. Should a "next page" link be displayed?
  9. If so, should it be omitted when you are on the last page (vs. displayed but disabled)?
  10. Should a "last page" link be displayed?
  11. If so, should it be omitted when you are on the last page (vs. displayed but disabled)?

To cover the full range of options, I propose the following modifications to paginate():

  • :window, :outer_window, :left, :right would be interpreted similarly to how they are now, except the supplied N would be the number of pages you actually get. 0 means disable for the outer windows.
  • Outer windows would be disabled by default in favor of first/last links.
  • Currently, "next" and "previous" links are always generated and their labels come from the translation database. I suggest making :next and :previous params to paginate(), with the same default values; if either is nil, don't generate the corresponding span.
  • Add :first and :last params to paginate() with suitable (present) defaults. If set to nil, these suppress the first and last links.
  • Currently, "next" and "previous" are rendered as empty spans (no link, no text) when they point to the current page. This is hard to style and inconsistent. Better: include a "disabled" or "inactive" class when appropriate, and always include the label text (but no link tag when current page). Users that want these tags to disappear completely when inapplicable can style them to display: none. (Similarly for "first" and "last".)
  • The double angle quotes currently used in the default labels for previous and next are potentially confusing because they bind more naturally to "first" and "last" than to "previous" and "next". (Consider a standard set of video or audio transport controls: << < stop > >>) Better: "Prev" and "Next" or "< Prev" and "Next >"

Under this regime, the defaults would be:

:window       => 3 or 4 (currently 4)
:outer_window => 0 unless :first == nil or :last == nil; in that case, 2
:next         => raw(t 'views.pagination.next'), with default translation "Next >"
:previous     => raw(t 'views.pagination.previous'), with default translation "< Prev"
:first        => raw(t 'views.pagination.first'), with default translation "<< First"
:last         => raw(t 'views.pagination.last'), with default translation "Last >>"

Some examples:

= paginate @things
[<< First] [< Prev] ... 6 7 8 [9] 10 11 12 ... [Next >] [Last >>]

= paginate @things :first => nil, :last => nil
[< Prev] 1 2 ... 6 7 8 [9] 10 11 12 ... 16 17 [Next >]

= paginate @things, :previous => nil, :next => nil
[<< First] ... 6 7 8 [9] 10 11 12 ... [Last >>]

= paginate @things, :first = nil, :left => 2, :window => 2
[< Prev] 1 2 ... 7 8 [9] 10 11 ... [Next >] [Last >>]

= paginate @things, :first => "First Page", :previous => "Previous", :next = "Next", :last => "Last Page"
 [First Page] [Prev] ... 6 7 8 [9] 10 11 12 ... [Next] [Last Page]

Named Routes and Sexy URLs

hi there,

i want kaminari to use the following route :

match "/:category(/page/:page)" => "viewer#index", :as => "category_index"

instead of going to the old route

/viewer/index?category=fiction&page=2

would i have to modiify the kaminari views? cant find any posts or comments from any1 with relation to this

weird problem (lazy loading?)

Great work! Thanks so much for providing a rails3-aware pagination solution.

currently having trouble in 0.10.2, as follows...

controller-code:
@Clients = Client.page(params[:page]).per(50)

works ok, as long as page is nil or 1 or 0

however, as soon as page is > 1, @Clients will be empty unless i do this:

puts @Clients

so if i don't do this, view will render empty page although there are results for the query.
Maybe an issue with Arel lazy loading. Will try to provide more details...
Odd thing is: it works for most of my models, but not for Client

Memory leak

Hi

Nice job with this gem. However, adding it to my Gemfile on a Rails3 app make my development environment leak 3MB of memory per request (using Mongrel).

Thibaut

Just a question about nested resources

This is really a trivial thing, but I was wondering if there was a way to do this... Take the following url as an example

/categories/2/articles

This is actually loading the articles controller, with the category_id parameter. Now, pagination works just fine, but if you click a pagination link, it moves you to a url like the following:

/articles/?category_id=2&page=2

This isn't a functional issue, as it works as intended, and loads the proper records, and page. What I would like to know is if you can specify a way to keep the url structure in tact, without having to duplicate code into a second controller.

/categories/2/articles?page=2

Here's a gist of my code.
https://gist.github.com/0b1d2f6891b02e630f01

nested param name is not working

try to use :param_name => "search[page]"
you will end with {:search => {:page => old_page}, "search[page]" => nil}. I guess you have to convert such a param_name to proper hash before merge, and merge it recursively .

Kaminari not paging my records

Hi;

Inside of my index action I have something like
@shipments = Shipment.order('date desc').page(params[:page])

If page is null, not passing the parameter or page == 1 then I got results and my @shipments variable get loaded, but if page >= 2 I got nothing, actually looking at Rails log no query is being issue.

My shipments table have hundred of records.

If I try the exact same line of code in Rails console it works, it issue the query

I'm using version 0.10.4 of kaminari.

Do you have any suggest on how to fix this?

Will pointlessly truncate a single page under some conditions

With the default settings, visiting page 8 will show "1 2 … 4 5 6 7 8 9" and so on.

While I see how this is consistent with the window sizes (the 3 falls right between the outer window and the inner window), it's not good end-user experience.

I suggest that the truncation should only appear if it covers more than one page.

Problem when using with JQuery

Hi, I'm trying to use kaminari in a project that uses jquery-rails.
After installing the gem and adding the appropriate code to the controller and index.html.erb
I get the following error:
Missing partial exercises/exercise with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html], :locale=>[:en, :en]}

Any ideas?

Regards,

Jens

view rendering considerably slower then will_paginate

I tested using this gem over will_paginate in some of my views/actions. However, when I compare the before and after render times of the partial including the paginate helper I notice a massive increase in render time. I have here a few examples:
with will_paginate:
135ms
212ms
with kaminari:
509ms
583ms
560ms
406ms

This was done in development mode. I suspect it has to do with the huge ammount of partial templates you are using. Im using rails 3.0.3 and ruby 1.9.2.

Setting per_page globally

I think there should be a way to set the default_per_page nicer than now. The constant DEFAULT_PER_PAGE can be set, but in a Rails application, there is no way to set it before the gem loads, so you're always overriding it, resulting in a warning.

Total count

How can I show the total count of the found set. So if I have 900 customers, showing 100 per page, I would like to show "100 of 900 Customers" Thanks!

Breaks Rails descendants method

I have following class in my project:

class User < AR::Base
  ...
  class Admin < User
  end

  class God < User
  end
  ...
end

Before creating a new user, you can selected the preferred type via a select-box. This select is filled by collecting all subclasses of User (User.descendants.collect(&:name)). Everything works fine unless kaminari is installed as a gem. After installing and using it, the descendants method always returns an empty array.

Overwriting existent scope :page

Hello,

because I have an association called page, I'm getting lots of these error messages:
Creating scope :page. Overwriting existing method Model.page
Is there a workaround for that?

Order-clause duplication when used with the meta_where gem

If you are using both kaminari and the meta_where gems in a project, you may get the columns in the order clause or the resulting SQL being repeated.

Full details, including how to reproduce are here: http://gist.github.com/885335

In summary, the problem occurs when you use lines like this in a controller:

@articles = Article.order(:title.desc).page(1)

Note the usage of :title.desc, a feature provided by the meta_where gem (this yields a MetaWhere::Column instance). This will result in the following SQL being generated:

SELECT "articles".* FROM "articles" ORDER BY "articles"."title" DESC, "articles"."title" DESC LIMIT 25 OFFSET 0

Notice the repetition in the ORDER BY clause. I'm not sure if this is a meta_where or a kaminari issue.

query with group(term) causes total_count to return a hash of {'term' => count}

Not sure how to give a simple example, but if you have an AREL query that includes a group(term) clause, getting @result.total_count returns a hash of the group terms and their counts, not a count for all the items found.

@ontology_terms = OntologyTerm.where("").group('term_id').page(1).per(10).order('name')

[#<OntologyTerm id: 2019, ontology_id: 6, term_id: "1150|RS:0001685", ncbo_id: "1150", name: " F344-Tg(Cyp1a1-Ren2)10", annotations_count: 0, created_at: "2009-11-09 10:00:00", updated_at: "2009-11-09 10:00:00">, #<OntologyTerm id: 4635, ontology_id: 6, term_id: "1150|RS:0001731", ncbo_id: "1150", name: "(F344.OLETF-(D14Rat23-D14Rat12)(D14Rat8-D14Rat26)/2...", annotations_count: 0, created_at: "2009-11-09 10:00:00", updated_at: "2009-11-09 10:00:00">, #<OntologyTerm id: 4637, ontology_id: 6, term_id: "1150|RS:0001733", ncbo_id: "1150", name: "(F344.OLETF-(D14Rat23-D14Rat12)(D14Rat8-D14Rat26)/2...", annotations_count: 0, created_at: "2009-11-09 10:00:00", updated_at: "2009-11-09 10:00:00">, #<OntologyTerm id: 4640, ontology_id: 6, term_id: "1150|RS:0001736", ncbo_id: "1150", name: "(F344.OLETF-(D7Mgh16-D7Mgh20)(D14Rat23-D14Rat12)/2T...", annotations_count: 0, created_at: "2009-11-09 10:00:00", updated_at: "2009-11-09 10:00:00">, #<OntologyTerm id: 4641, ontology_id: 6, term_id: "1150|RS:0001737", ncbo_id: "1150", name: "(F344.OLETF-(D7Mgh16-D7Mgh20)/Tj X F344.OLETF-(D8Ra...", annotations_count: 0, created_at: "2009-11-09 10:00:00", updated_at: "2009-11-09 10:00:00">, #<OntologyTerm id: 4643, ontology_id: 6, term_id: "1150|RS:0001739", ncbo_id: "1150", name: "(F344.OLETF-(D8Rat54-D8Mgh17)/2Tj x F344.Cg-Leprfa(...", annotations_count: 0, created_at: "2009-11-09 10:00:00", updated_at: "2009-11-09 10:00:00">, #<OntologyTerm id: 4644, ontology_id: 6, term_id: "1150|RS:0001740", ncbo_id: "1150", name: "(F344.OLETF-(D8Rat54-D8Mgh17)/2Tj x F344.Cg-Leprfa(...", annotations_count: 0, created_at: "2009-11-09 10:00:00", updated_at: "2009-11-09 10:00:00">, #<OntologyTerm id: 4645, ontology_id: 6, term_id: "1150|RS:0001741", ncbo_id: "1150", name: "(F344.OLETF-(D8Rat54-D8Mgh17)/2Tj x F344.Cg-Leprfa(...", annotations_count: 0, created_at: "2009-11-09 10:00:00", updated_at: "2009-11-09 10:00:00">, #<OntologyTerm id: 471, ontology_id: 6, term_id: "1150|RS:0000003", ncbo_id: "1150", name: "13M", annotations_count: 0, created_at: "2009-11-09 10:00:00", updated_at: "2009-11-09 10:00:00">, #<OntologyTerm id: 423, ontology_id: 6, term_id: "1150|RS:0000270", ncbo_id: "1150", name: "A2", annotations_count: 2, created_at: "2009-11-09 10:00:00", updated_at: "2009-11-09 10:00:00">] 

@ontology_terms.total_count

{"1150|RS:0001685"=>1, "1150|RS:0001731"=>1, "1150|RS:0001733"=>1, "1150|RS:0001736"=>1, "1150|RS:0001737"=>1, "1150|RS:0001739"=>1}...snipped

Outer windows are off by one

When you specify :outer_window => 1 (as in the default), you actually get two pages in each outer window, e.g.:

1 2 ... <more pages> ... 9 10

More generally, you always get one more page than you ask for. This may be done for will_paginate compatibility, but it seems a little strange and perhaps a case in which reasonable behavior would be more valuable than compatibility.

Additionally, it would be helpful to be able to disable the outer windows entirely by setting :outer_window to 0. Currently, this gives you one-page outer windows.

Problems when using meta_search + kaminari (undefined method).

Hi,

When I try to paginate on meta_search results it just tells me that there is no method like "page"

def index
  @search = Article.search(params[:search])
  @articles = @search.page params[:page]
  respond_with @articles
 end

Error is:
undefined method `page' for #MetaSearch::Searches::User:0xb55d3440

Example from meta_search gem which is working flawlessly with will_paginate is:
def index
@search = Article.search(params[:search])
@articles = @search.paginate(:page => params[:page])
respond_with @articles
end

undefined method `safe_concat' for nil:NilClass when used with HAML

ページ全体をhamlで書いている場合に、= paginate @entries でpaginationを出力しようとした場合に、「undefined method `safe_concat' for nil:NilClass」というエラーになりました。
(0.9.9までは大丈夫だった書き方)

rails generate kaminari:views default -e haml を実行しapp/views/kaminari以下にファイルを作ると、hamlの場合でもpaginationが出力できるようになり、特に問題はありません。

0.9.12で「Moved the whole pagination logic to the paginator partial」とあるので、そのためかもしれません。

ドキュメントのどこかに「hamlを使う場合は最初に rails generate kaminari:views default -e haml を実行しましょう」のようなことが書かれているほうが分かりやすいかもしれません。

以下、試した際にviewに出たエラーです。
バニラな環境で再現できます。

undefined method `safe_concat' for nil:NilClass

Extracted source (around line #9):

6: remote: data-remote
7: paginator: the paginator that renders the pagination tags inside
8: -%>
9: <%= paginator.render do -%>
10:


11: <%= current_page > 1 ? prev_link_tag : prev_span_tag %>
12: <% each_page do |page| -%>

offset error

undefined method `offset' for #Class:0x1046b4ae0
rails 3.0.0

trace:

activerecord (3.0.0) lib/active_record/base.rb:1016:in method_missing' kaminari (0.9.2) lib/kaminari/active_record.rb:18:ininherited'
activerecord (3.0.0) lib/active_record/named_scope.rb:107:in call' activerecord (3.0.0) lib/active_record/named_scope.rb:107:inpage'
app/controllers/opportunities_controller.rb:11:in index' actionpack (3.0.0) lib/action_controller/metal/implicit_render.rb:4:insend_action'
actionpack (3.0.0) lib/action_controller/metal/implicit_render.rb:4:in send_action' actionpack (3.0.0) lib/abstract_controller/base.rb:150:inprocess_action'
actionpack (3.0.0) lib/action_controller/metal/rendering.rb:11:in process_action' actionpack (3.0.0) lib/abstract_controller/callbacks.rb:18:inprocess_action'
activesupport (3.0.0) lib/active_support/callbacks.rb:460:in _run__1183185049__process_action__199225275__callbacks' activesupport (3.0.0) lib/active_support/callbacks.rb:409:insend'
activesupport (3.0.0) lib/active_support/callbacks.rb:409:in _run_process_action_callbacks' activesupport (3.0.0) lib/active_support/callbacks.rb:93:insend'
activesupport (3.0.0) lib/active_support/callbacks.rb:93:in run_callbacks' actionpack (3.0.0) lib/abstract_controller/callbacks.rb:17:inprocess_action'
actionpack (3.0.0) lib/action_controller/metal/instrumentation.rb:30:in process_action' activesupport (3.0.0) lib/active_support/notifications.rb:52:ininstrument'
activesupport (3.0.0) lib/active_support/notifications/instrumenter.rb:21:in instrument' activesupport (3.0.0) lib/active_support/notifications.rb:52:ininstrument'
actionpack (3.0.0) lib/action_controller/metal/instrumentation.rb:29:in process_action' actionpack (3.0.0) lib/action_controller/metal/rescue.rb:17:inprocess_action'
newrelic_rpm (2.13.4) lib/new_relic/agent/instrumentation/rails3/action_controller.rb:34:in process_action' newrelic_rpm (2.13.4) lib/new_relic/agent/instrumentation/controller_instrumentation.rb:252:inperform_action_with_newrelic_trace'
newrelic_rpm (2.13.4) lib/new_relic/agent/method_tracer.rb:141:in trace_execution_scoped' newrelic_rpm (2.13.4) lib/new_relic/agent/instrumentation/controller_instrumentation.rb:247:inperform_action_with_newrelic_trace'
newrelic_rpm (2.13.4) lib/new_relic/agent/instrumentation/rails3/action_controller.rb:33:in process_action' actionpack (3.0.0) lib/abstract_controller/base.rb:119:inprocess'
actionpack (3.0.0) lib/abstract_controller/rendering.rb:40:in process' actionpack (3.0.0) lib/action_controller/metal.rb:133:indispatch'
actionpack (3.0.0) lib/action_controller/metal/rack_delegation.rb:14:in dispatch' actionpack (3.0.0) lib/action_controller/metal.rb:173:inaction'
actionpack (3.0.0) lib/action_dispatch/routing/route_set.rb:62:in call' actionpack (3.0.0) lib/action_dispatch/routing/route_set.rb:62:indispatch'
actionpack (3.0.0) lib/action_dispatch/routing/route_set.rb:27:in call' rack-mount (0.6.13) lib/rack/mount/route_set.rb:148:incall'
rack-mount (0.6.13) lib/rack/mount/code_generation.rb:93:in recognize' rack-mount (0.6.13) lib/rack/mount/code_generation.rb:68:inoptimized_each'
rack-mount (0.6.13) lib/rack/mount/code_generation.rb:92:in recognize' rack-mount (0.6.13) lib/rack/mount/route_set.rb:139:incall'
actionpack (3.0.0) lib/action_dispatch/routing/route_set.rb:492:in call' oa-core (0.1.6) lib/omniauth/strategy.rb:50:incall_app!'
oa-core (0.1.6) lib/omniauth/strategy.rb:32:in call!' oa-core (0.1.6) lib/omniauth/strategy.rb:19:incall'
oa-core (0.1.6) lib/omniauth/builder.rb:30:in call' newrelic_rpm (2.13.4) lib/new_relic/rack/developer_mode.rb:20:incall'
warden (0.10.7) lib/warden/manager.rb:35:in call' warden (0.10.7) lib/warden/manager.rb:34:incatch'
warden (0.10.7) lib/warden/manager.rb:34:in call' actionpack (3.0.0) lib/action_dispatch/middleware/best_standards_support.rb:17:incall'
actionpack (3.0.0) lib/action_dispatch/middleware/head.rb:14:in call' rack (1.2.1) lib/rack/methodoverride.rb:24:incall'
actionpack (3.0.0) lib/action_dispatch/middleware/params_parser.rb:21:in call' actionpack (3.0.0) lib/action_dispatch/middleware/flash.rb:182:incall'
actionpack (3.0.0) lib/action_dispatch/middleware/session/abstract_store.rb:149:in call' actionpack (3.0.0) lib/action_dispatch/middleware/cookies.rb:287:incall'
activerecord (3.0.0) lib/active_record/query_cache.rb:32:in call' activerecord (3.0.0) lib/active_record/connection_adapters/abstract/query_cache.rb:28:incache'
activerecord (3.0.0) lib/active_record/query_cache.rb:12:in cache' activerecord (3.0.0) lib/active_record/query_cache.rb:31:incall'
activerecord (3.0.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:355:in call' actionpack (3.0.0) lib/action_dispatch/middleware/callbacks.rb:46:incall'
activesupport (3.0.0) lib/active_support/callbacks.rb:415:in _run_call_callbacks' actionpack (3.0.0) lib/action_dispatch/middleware/callbacks.rb:44:incall'
rack (1.2.1) lib/rack/sendfile.rb:107:in call' actionpack (3.0.0) lib/action_dispatch/middleware/remote_ip.rb:48:incall'
actionpack (3.0.0) lib/action_dispatch/middleware/show_exceptions.rb:46:in call' railties (3.0.0) lib/rails/rack/logger.rb:13:incall'
rack (1.2.1) lib/rack/runtime.rb:17:in call' activesupport (3.0.0) lib/active_support/cache/strategy/local_cache.rb:72:incall'
rack (1.2.1) lib/rack/lock.rb:11:in call' rack (1.2.1) lib/rack/lock.rb:11:insynchronize'
rack (1.2.1) lib/rack/lock.rb:11:in call' actionpack (3.0.0) lib/action_dispatch/middleware/static.rb:30:incall'
railties (3.0.0) lib/rails/application.rb:168:in call' railties (3.0.0) lib/rails/application.rb:77:insend'
railties (3.0.0) lib/rails/application.rb:77:in method_missing' railties (3.0.0) lib/rails/rack/log_tailer.rb:14:incall'
rack (1.2.1) lib/rack/content_length.rb:13:in call' rack (1.2.1) lib/rack/handler/webrick.rb:52:inservice'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in service' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/httpserver.rb:65:inrun'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:173:in start_thread' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:162:instart'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:162:in start_thread' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:95:instart'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:92:in each' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:92:instart'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:23:in start' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:82:instart'
rack (1.2.1) lib/rack/handler/webrick.rb:13:in run' rack (1.2.1) lib/rack/server.rb:213:instart'
railties (3.0.0) lib/rails/commands/server.rb:65:in start' railties (3.0.0) lib/rails/commands.rb:30 railties (3.0.0) lib/rails/commands.rb:27:intap'
railties (3.0.0) lib/rails/commands.rb:27
script/rails:6:in `require'
script/rails:6

page scope eliminates previous criteria in Mongoid

Have tested this against version 0.10.2 and Mongoid 2.0.0.rc.7

Given the following model:

class Foo
  include Mongoid::Document
  field :value, :type => Integer
  scope :below, lambda {|v| where( :value.lt => v )}
  scope :above, lambda {|v| where( :value.gt => v )}
end

a call to the :page scope will eliminate any previous criteria made in the call chain prior to the call. For example:

Foo.above( 5 ).below( 10 )
 => #<Mongoid::Criteria
  selector: {:value=>{"$gt"=>5, "$lt"=>10}},
  options:  {},
  class:    Foo,
  embedded: false>
Foo.above( 5 ).below( 10 ).page( 1 )
 => #<Mongoid::Criteria
  selector: {},
  options:  {:limit=>25, :skip=>0},
  class:    Foo,
  embedded: false>

However, calling :page first seems to work alright:

Foo.page( 1 ).below( 5 )
 => #<Mongoid::Criteria
  selector: {:value=>{"$lt"=>5}},
  options:  {:limit=>25, :skip=>0},
  class:    Foo,
  embedded: false>

The definition of the :page scope (in models/mongoid_extension.rb) seems to be correct enough; adding in a limit or offset criteria on a method call chain does not seem to be an issue:

Foo.below( 5 ).limit( 10 ).offset( 5 )
 => #<Mongoid::Criteria
  selector: {:value=>{"$lt"=>5}},
  options:  {:limit=>10, :skip=>5},
  class:    Foo,
  embedded: false>

To reiterate: this seems to completely wipe out the previous criteria stack made in the method call chain. I used scopes with :where, above, but the issue occurs with other criteria operations as well. For instance, :asc/:desc, used for ordering by specified fields, results in the same issue.

Keep param in the link to first page

I've noticed kaminari's helper adds the page parameter to every link except to the link for the first page.

That usually would work fine, but I've got a use case where it doesn't work as expected.

In an application I'm working on there's an admin area where, if no page param is provided, the last visited page by the user is loaded.

The reasoning for this follows. In a traditional situation:

  • admin makes it to page 17 of posts, where there are two posts to modify.
  • admin modifies the first post and saves it.
  • admin goes back to the posts index.
  • admin has to make all the way to page 17 again to modify the second one.

My solution (which has its drawbacks, of course) is saving page 17 as last page visited, and directing the admin there when there's no page parameter.

Everything would work (and I can't think of situations that would be broken) if the first page link had the page param as well. Here's a small patch:

https://gist.github.com/846609

Unfortunately I've tried to provide a test case, but failed miserably with the template stubbing.

Thanks.

Other ORM like mongoid

Is it possible that this become easily extensible with other ORM like mongoid. I saw there is the active_record.rb in Railties. Can we do some configuration and use other file like mongoid.rb to change the data store and still use this paginator.

A page can be both current and first or last

The default paginator has separate partials for the current page, the first page, and the last page. However, these are not mutually exclusive sets. To facilitate styling, the paginator should emit page spans with both the current and first/last classes when this is appropriate.

Perhaps there should just be one page partial: include "first" class if page.first?, include "last" class if page.last?, include "current" class if page.current?, and link the page number if not page.current?.

Using paginate with escape_javascript

I have problems using paginate with an AJAX call. I want to replace the pagination div like this:

$('.pagination').replaceWith('<%= escape_javascript(paginate(collection, :params => paginate_params).to_s) %>');

I tried multiple versions, but I can't get it working. I get multiple JS errors when I want to update the view.

:param_name not working

Hi,

No matter what I do the page parameter name won't change. Running version (0.10.1)

paginate @users, :param_name => :pagina

Any ideas?

Sunspot support

Do you have any plans to support not ORM solutions like sunspot ?

General configuration options

I've got pagination in a few places in my application. For all of them I'd like to display the same number of results, and with the same pagination options.

So far, I'm setting the number of results in an initializer:
Kaminari::DEFAULT_PER_PAGE = 15 # Doesn't feel right

And creating a helper for the pagination links:
def custom_paginate(records)
paginate records, :window => 3
end

Then from the other places I call the helper:
= custom_paginate(@pages)

Perhaps there could be a simpler way to set some these options in order to overried Kaminari's defaults?

Thanks!

paginate() Method

It would be nice if there was a paginate method similar to will_paginates ( paginate({ :page => 1, :per_page => 10 }) ) so that when coming from will_paginate to kaminari we don't have to change any code.

Item.page(2).present? is false even when there are items

Not sure if this is a bug with Rails, Kaminari or what, but:

DEV 12:25:48 >> Item.count
SQL (1.5ms)  SELECT COUNT(*) FROM `items`
=> 574
DEV 12:24:33 >> Item.page(2).present?
SQL (1.6ms)  SELECT COUNT(*) FROM `items` LIMIT 25 OFFSET 25
=> false
DEV 12:25:43 >> Item.page(2).length
Item Load (0.9ms)  SELECT `items`.* FROM `items` LIMIT 25 OFFSET 25
=> 25

If you load the collection before using present?, it works:

DEV 12:27:08 >> items = Item.page(2); items.all; items.present?
Item Load (13.2ms)  SELECT `items`.* FROM `items` LIMIT 25 OFFSET 25
=> true

But remove the items.all; bit and it will fail like above.

I use MySQL.

comparing with will_paginate

Hi! Can someone explain why it's better than will_paginate? Some feature?
I'm using will_paginate and mongoid and it's working well right know. Tks!

Issue with mongoid

I got a weird issue with an app rails3/mongoid

In my index controller, when calling .page(params[:page]), I got:

undefined method `conditions' for nil:NilClass

.bundle/ruby/1.9.1/gems/activesupport-3.0.5/lib/active_support/whiny_nil.rb:48:in method_missing' (eval):3:inpage'
.bundle/ruby/1.9.1/gems/kaminari-0.10.4/lib/kaminari/models/mongoid_extension.rb:10:in page' app/controllers/admin/images_controller.rb:7:inindex'

As the backtrace is not very verbose, I debugged and targetted the error here:
kaminari-0.10.4/lib/kaminari/models/mongoid_extension.rb:10
self.klass.page(*args).criteria.merge(self)
(rdb:2) pp self.klass.page
NoMethodError Exception: undefined method `conditions' for nil:NilClass

Any thoughts on this?

Confusion when displaying second+ pages: .count doesn't work any more

Since kaminari will append an offset and limit to each query, when trying to use the default .count method AREL will try to do a count with the limit and offset, which doesn't work. Likewise using something like .any? I ran into this bug because I have some logic that checks to see if any records exist before displaying them, otherwise I show a "There is no data" placeholder message. I was doing the check with data.any? which doesn't work after the first page.

I see that you added a total_count method which specifically excludes limit and offset, and I can use that in my code, but I wouldn't have known without digging through the code. Is it possible to override count to do the same thing, or does that have the potential to break too may things?

2nd Page results not being retrieved

On a table I have of users (total 3). I set the per_page to 2 so I can test out pagination. The first two users get displayed but when I go to the next page, the laster user doesn't show up. Looking in the SQL code, I see you are doing the following:

SQL (0.3ms) SELECT COUNT() FROM users WHERE users.active = 1 LIMIT 2 OFFSET 0
User Load (0.2ms) SELECT users.
FROM users WHERE users.active = 1 ORDER BY id ASC LIMIT 2 OFFSET 0

This works to produce the first two users. When I click on the 2n'd page, no users get loaded. The SQL code is:

SQL (0.3ms) SELECT COUNT(*) FROM users WHERE users.active = 1 LIMIT 2 OFFSET 2

When I test out this SQ code myslef, it shows that:

SQL (0.3ms) SELECT COUNT(*) FROM users WHERE users.active = 1 LIMIT 2 OFFSET 0

it returned 3 (I would think it would return 2)

SQL (0.3ms) SELECT COUNT(*) FROM users WHERE users.active = 1 LIMIT 2 OFFSET 2

returns 0 (I would think it would return 1)

I'm using MySql 5.1.51 on MacBook Pro running Rail 3.0.4.

My User controller is issuing this command:

@users = User.order('id DESC').page(params[:page]).per(2)

I'm not sure what is wrong with the SQL code you are generating but it isn't working right for me. Am I doing something wrong?

page_entries_info for Kaminari (like will_paginate has)???

Is there a way to get the same view helper output from will_paginate's page_entries_info helper in kaminari? I've looked at all the documentation and don't see this.

I'm sure I can generate it by passing the collection i specify from <%= paginate @collection %> as a locals hash, then deriving it, but it would be nice to have this built in if its somewhere.

Here's the will_paginate readme:
<%= page_entries_info @posts %> #-> Displaying posts 6 - 10 of 26 in total

Has anyone figured this out? If not, I suppose I can write it and submit it back :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.