[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-7663":3},{"id":4,"name":5,"fullName":6,"owner":5,"repo":5,"description":7,"homepage":8,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":15,"forks30d":15,"starsTrendScore":18,"compositeScore":19,"rankGlobal":9,"rankLanguage":9,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":9,"pushedAt":9,"updatedAt":28,"readmeContent":29,"aiSummary":30,"trendingCount":15,"starSnapshotCount":15,"syncStatus":16,"lastSyncTime":31,"discoverSource":32},7663,"kaminari","kaminari\u002Fkaminari","⚡ A Scope & Engine based, clean, powerful, customizable and sophisticated paginator for Ruby webapps","https:\u002F\u002Fgithub.com\u002Fkaminari\u002Fkaminari\u002Fwiki",null,"Ruby",8680,1076,117,50,0,2,14,6,71.5,"MIT License",false,"master",true,[5,25,26,27],"pagination","rails","ruby","2026-06-12 04:00:35","# Kaminari [![Build Status](https:\u002F\u002Fgithub.com\u002Fkaminari\u002Fkaminari\u002Factions\u002Fworkflows\u002Fmain.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fkaminari\u002Fkaminari\u002Factions) [![Code Climate](https:\u002F\u002Fcodeclimate.com\u002Fgithub\u002Fkaminari\u002Fkaminari\u002Fbadges\u002Fgpa.svg)](https:\u002F\u002Fcodeclimate.com\u002Fgithub\u002Fkaminari\u002Fkaminari)\n\nA Scope & Engine based, clean, powerful, customizable and sophisticated paginator for modern web app frameworks and ORMs\n\n## Features\n\n### Clean\nDoes not globally pollute `Array`, `Hash`, `Object` or `AR::Base`.\n\n### Easy to Use\nJust bundle the gem, then your models are ready to be paginated.\nNo configuration required.\nDon't have to define anything in your models or helpers.\n\n### Simple Scope-based API\nEverything is method chainable with less \"Hasheritis\". You know, that's the modern Rails way.\nNo special collection class or anything for the paginated values, instead using a general `AR::Relation` instance.\nSo, of course you can chain any other conditions before or after the paginator scope.\n\n### Customizable Engine-based I18n-aware Helpers\nAs 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.\nSo, you can easily modify their behaviour, style or whatever by overriding partial templates.\n\n### ORM & Template Engine Agnostic\nKaminari supports multiple ORMs (ActiveRecord, DataMapper, Mongoid, MongoMapper), multiple web frameworks (Rails, Sinatra, Grape), and multiple template engines (ERB, Haml, Slim).\n\n### Modern\nThe pagination helper outputs the HTML5 `\u003Cnav>` tag by default. Plus, the helper supports Rails unobtrusive Ajax.\n\n\n## Supported Versions\n\n* Ruby 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, 3.3\n\n* Rails 4.1, 4.2, 5.0, 5.1, 5.2, 6.0, 6.1, 7.0, 7.1, 7.2, 8.0\n\n* Sinatra 1.4, 2.0\n\n* Haml 3+\n\n* Mongoid 3+\n\n* MongoMapper 0.9+\n\n* DataMapper 1.1.0+\n\n\n## Installation\n\nTo install kaminari on the default Rails stack, just put this line in your Gemfile:\n\n```ruby\ngem 'kaminari'\n```\n\nThen bundle:\n\n```sh\n% bundle\n```\n\nIf you're building non-Rails or non-ActiveRecord app and want the pagination feature on it, please take a look at [Other Framework\u002FLibrary Support](#other-frameworklibrary-support) section.\n\n\n## Query Basics\n\n### The `page` Scope\n\nTo fetch the 7th page of users (default `per_page` is 25)\n\n```ruby\nUser.page(7)\n```\n\nNote: pagination starts at page 1, not at page 0 (page(0) will return the same results as page(1)).\n\nKaminari does not add an `order` to queries. To avoid surprises, you should generally include an order in paginated queries. For example:\n\n```ruby\nUser.order(:name).page(7)\n```\n\nYou can get page numbers or page conditions by using below methods.\n```ruby\nUser.count                     #=> 1000\nUser.page(1).limit_value       #=> 20\nUser.page(1).total_pages       #=> 50\nUser.page(1).current_page      #=> 1\nUser.page(1).next_page         #=> 2\nUser.page(2).prev_page         #=> 1\nUser.page(1).first_page?       #=> true\nUser.page(50).last_page?       #=> true\nUser.page(100).out_of_range?   #=> true\n```\n\n### The `per` Scope\n\nTo show a lot more users per each page (change the `per` value)\n\n```ruby\nUser.order(:name).page(7).per(50)\n```\n\nNote that the `per` scope is not directly defined on the models but is just a method defined on the page scope.\nThis is absolutely reasonable because you will never actually use `per` without specifying the `page` number.\n\nKeep in mind that `per` internally utilizes `limit` and so it will override any `limit` that was set previously.\nAnd if you want to get the size for all request records you can use `total_count` method:\n\n```ruby\nUser.count                     #=> 1000\na = User.limit(5); a.count     #=> 5\na.page(1).per(20).size         #=> 20\na.page(1).per(20).total_count  #=> 1000\n```\n\n### The `padding` Scope\n\nOccasionally you need to pad a number of records that is not a multiple of the page size.\n\n```ruby\nUser.order(:name).page(7).per(50).padding(3)\n```\n\nNote that the `padding` scope also is not directly defined on the models.\n\n### Unscoping\n\nIf for some reason you need to unscope `page` and `per` methods you can call `except(:limit, :offset)`\n\n```ruby\nusers = User.order(:name).page(7).per(50)\nunpaged_users = users.except(:limit, :offset) # unpaged_users will not use the kaminari scopes\n```\n\n## Configuring Kaminari\n\n### General Configuration Options\n\nYou can configure the following default values by overriding these values using `Kaminari.configure` method.\n\n    default_per_page      # 25 by default\n    max_per_page          # nil by default\n    max_pages             # nil by default\n    window                # 4 by default\n    outer_window          # 0 by default\n    left                  # 0 by default\n    right                 # 0 by default\n    page_method_name      # :page by default\n    param_name            # :page by default\n    params_on_first_page  # false by default\n\nThere's a handy generator that generates the default configuration file into config\u002Finitializers directory.\nRun the following generator command, then edit the generated file.\n\n```sh\n% rails g kaminari:config\n```\n\n### Changing `page_method_name`\n\nYou 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.\n\n\n### Configuring Default per_page Value for Each Model by `paginates_per`\n\nYou can specify default `per_page` value per each model using the following declarative DSL.\n\n```ruby\nclass User \u003C ActiveRecord::Base\n  paginates_per 50\nend\n```\n\n### Configuring Max per_page Value for Each Model by `max_paginates_per`\n\nYou can specify max `per_page` value per each model using the following declarative DSL.\nIf the variable that specified via `per` scope is more than this variable, `max_paginates_per` is used instead of it.\nDefault value is nil, which means you are not imposing any max `per_page` value.\n\n```ruby\nclass User \u003C ActiveRecord::Base\n  max_paginates_per 100\nend\n```\n\n### Configuring max_pages Value for Each Model by `max_pages`\n\nYou can specify `max_pages` value per each model using the following declarative DSL.\nThis value restricts the total number of pages that can be returned.  Useful for setting limits on large collections.\n\n```ruby\nclass User \u003C ActiveRecord::Base\n  max_pages 100\nend\n```\n\n### Configuring params_on_first_page when using ransack_memory\n\nIf you are using [the `ransack_memory` gem](https:\u002F\u002Fgithub.com\u002Frichardrails\u002Fransack_memory) and experience problems navigating back to the previous or first page, set the `params_on_first_page` setting to `true`.\n\n## Controllers\n\n### The Page Parameter Is in `params[:page]`\n\nTypically, your controller code will look like this:\n\n```ruby\n@users = User.order(:name).page params[:page]\n```\n\n\n## Views\n\n### The Same Old Helper Method\n\nJust call the `paginate` helper:\n\n```erb\n\u003C%= paginate @users %>\n```\n\nThis will render several `?page=N` pagination links surrounded by an HTML5 `\u003Cnav>` tag.\n\n\n## Helpers\n\n### The `paginate` Helper Method\n\n```erb\n\u003C%= paginate @users %>\n```\n\nThis would output several pagination links such as `« First ‹ Prev ... 2 3 4 5 6 7 8 9 10 ... Next › Last »`.\n\n### Specifying the \"inner window\" Size (4 by default)\n\n```erb\n\u003C%= paginate @users, window: 2 %>\n```\n\nThis would output something like `... 5 6 7 8 9 ...` when 7 is the current\npage.\n\n### Specifying the \"outer window\" Size (0 by default)\n\n```erb\n\u003C%= paginate @users, outer_window: 3 %>\n```\n\nThis would output something like `1 2 3 ...(snip)... 18 19 20` while having 20 pages in total.\n\n### Outer Window Can Be Separately Specified by left, right (0 by default)\n\n```erb\n\u003C%= paginate @users, left: 1, right: 3 %>\n```\n\nThis would output something like `1 ...(snip)... 18 19 20` while having 20 pages in total.\n\n### Changing the Parameter Name (`:param_name`) for the Links\n\n```erb\n\u003C%= paginate @users, param_name: :pagina %>\n```\n\nThis would modify the query parameter name on each links.\n\n### Extra Parameters (`:params`) for the Links\n\n```erb\n\u003C%= paginate @users, params: {controller: 'foo', action: 'bar', format: :turbo_stream} %>\n```\n\nThis would modify each link's `url_option`. `:controller` and `:action` might be the keys in common.\n\n### Ajax Links (via rails-ujs, works with Rails \u003C 7.2)\n\n```erb\n\u003C%= paginate @users, remote: true %>\n```\n\nThis would add `data-remote=\"true\"` to all the links inside.\n\n### Specifying an Alternative Views Directory (default is kaminari\u002F)\n\n```erb\n\u003C%= paginate @users, views_prefix: 'templates' %>\n```\n\nThis would search for partials in `app\u002Fviews\u002Ftemplates\u002Fkaminari`.\nThis option makes it easier to do things like A\u002FB testing pagination templates\u002Fthemes, using new\u002Fold templates at the same time as well as better integration with other gems such as [cells](https:\u002F\u002Fgithub.com\u002Fapotonick\u002Fcells).\n\n### The `link_to_next_page` and `link_to_previous_page` (aliased to `link_to_prev_page`) Helper Methods\n\n```erb\n\u003C%= link_to_next_page @items, 'Next Page' %>\n```\n\nThis simply renders a link to the next page. This would be helpful for creating a Twitter-like pagination feature.\n\nThe helper methods support a `params` option to further specify the link. If `format` needs to be set, include it in the `params` hash.\n\n```erb\n\u003C%= link_to_next_page @items, 'Next Page', params: {controller: 'foo', action: 'bar', format: :turbo_stream} %>\n```\n\n### The `page_entries_info` Helper Method\n\n```erb\n\u003C%= page_entries_info @posts %>\n```\n\nThis renders a helpful message with numbers of displayed vs. total entries.\n\nBy default, the message will use the humanized class name of objects in collection: for instance, \"project types\" for ProjectType models.\nThe namespace will be cut out and only the last name will be used. Override this with the `:entry_name` parameter:\n\n```erb\n\u003C%= page_entries_info @posts, entry_name: 'item' %>\n#=> Displaying items 6 - 10 of 26 in total\n```\n\n### The `rel_next_prev_link_tags` Helper Method\n\n```erb\n\u003C%= rel_next_prev_link_tags @users %>\n```\n\nThis renders the rel next and prev link tags for the head.\n\n### The `path_to_next_page` Helper Method\n\n```erb\n\u003C%= path_to_next_page @users %>\n```\n\nThis returns the server relative path to the next page.\n\n### The `path_to_prev_page` Helper Method\n\n```erb\n\u003C%= path_to_prev_page @users %>\n```\n\nThis returns the server relative path to the previous page.\n\n\n## I18n and Labels\n\nThe default labels for 'first', 'last', 'previous', '...' and 'next' are stored in the I18n yaml inside the engine, and rendered through I18n API.\nYou 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\u002Fconfig\u002Flocales` directory.\n\n```yaml\nen:\n  views:\n    pagination:\n      first: \"&laquo; First\"\n      last: \"Last &raquo;\"\n      previous: \"&lsaquo; Prev\"\n      next: \"Next &rsaquo;\"\n      truncate: \"&hellip;\"\n  helpers:\n    page_entries_info:\n      one_page:\n        display_entries:\n          zero: \"No %{entry_name} found\"\n          one: \"Displaying \u003Cb>1\u003C\u002Fb> %{entry_name}\"\n          other: \"Displaying \u003Cb>all %{count}\u003C\u002Fb> %{entry_name}\"\n      more_pages:\n        display_entries: \"Displaying %{entry_name} \u003Cb>%{first}–%{last}\u003C\u002Fb> of \u003Cb>%{total}\u003C\u002Fb> in total\"\n```\n\nIf you use non-English localization see [i18n rules](https:\u002F\u002Fgithub.com\u002Fsvenfuchs\u002Fi18n\u002Fblob\u002Fmaster\u002Ftest\u002Ftest_data\u002Flocales\u002Fplurals.rb) for changing\n`one_page:display_entries` block.\n\n\n## Customizing the Pagination Helper\n\nKaminari includes a handy template generator.\n\n### To Edit Your Paginator\n\nRun the generator first,\n\n```sh\n% rails g kaminari:views default\n```\n\nthen edit the partials in your app's `app\u002Fviews\u002Fkaminari\u002F` directory.\n\n### For Haml\u002FSlim Users\n\nYou can use the [html2haml gem](https:\u002F\u002Fgithub.com\u002Fhaml\u002Fhtml2haml) or the [html2slim gem](https:\u002F\u002Fgithub.com\u002Fslim-template\u002Fhtml2slim) to convert erb templates.\nThe kaminari gem will automatically pick up haml\u002Fslim templates if you place them in `app\u002Fviews\u002Fkaminari\u002F`.\n\n### Multiple Templates\n\nIn case you need different templates for your paginator (for example public and admin), you can pass `--views-prefix directory` like this:\n\n```sh\n% rails g kaminari:views default --views-prefix admin\n```\n\nthat will generate partials in `app\u002Fviews\u002Fadmin\u002Fkaminari\u002F` directory.\n\n### Themes\n\nThe generator has the ability to fetch several sample template themes from the external repository (https:\u002F\u002Fgithub.com\u002Famatsuda\u002Fkaminari_themes) in addition to the bundled \"default\" one, which will help you creating a nice looking paginator.\n\n```sh\n% rails g kaminari:views THEME\n```\n\nTo see the full list of available themes, take a look at the themes repository, or just hit the generator without specifying `THEME` argument.\n\n```sh\n% rails g kaminari:views\n```\n\n### Multiple Themes\n\nTo utilize multiple themes from within a single application, create a directory within the app\u002Fviews\u002Fkaminari\u002F and move your custom template files into that directory.\n\n```sh\n% rails g kaminari:views default (skip if you have existing kaminari views)\n% cd app\u002Fviews\u002Fkaminari\n% mkdir my_custom_theme\n% cp _*.html.* my_custom_theme\u002F\n```\n\nNext, reference that directory when calling the `paginate` method:\n\n```erb\n\u003C%= paginate @users, theme: 'my_custom_theme' %>\n```\n\nCustomize away!\n\nNote: if the theme isn't present or none is specified, kaminari will default back to the views included within the gem.\n\n\n## Paginating Without Issuing SELECT COUNT Query\n\nGenerally 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.\nFor such use case, Kaminari provides `without_count` mode that creates a paginatable collection without counting the number of all records.\nThis may be helpful when you're dealing with a very large dataset because counting on a big table tends to become slow on RDBMS.\n\nJust add `.without_count` to your paginated object:\n\n```ruby\nUser.page(3).without_count\n```\n\nIn your view file, you can only use simple helpers like the following instead of the full-featured `paginate` helper:\n\n```erb\n\u003C%= link_to_prev_page @users, 'Previous Page' %>\n\u003C%= link_to_next_page @users, 'Next Page' %>\n```\n\n\n## Paginating a Generic Array object\n\nKaminari 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).\n`Kaminari::paginate_array` method converts your Array object into a paginatable Array that accepts `page` method.\n\n```ruby\n@paginatable_array = Kaminari.paginate_array(my_array_object).page(params[:page]).per(10)\n```\n\nYou 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:\n\n```ruby\n@paginatable_array = Kaminari.paginate_array([], total_count: 145).page(params[:page]).per(10)\n```\n\nor, in the case of using an external API to source the page of data:\n```ruby\npage_size = 10\none_page = get_page_of_data params[:page], page_size\n@paginatable_array = Kaminari.paginate_array(one_page.data, total_count: one_page.total_count).page(params[:page]).per(page_size)\n```\n\n\n## Creating Friendly URLs and Caching\n\nBecause 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`:\n\n```ruby\nresources :my_resources do\n  get 'page\u002F:page', action: :index, on: :collection\nend\n```\n\nIf you are using Rails 4 or later, you can simplify route definitions by using `concern`:\n\n```ruby\nconcern :paginatable do\n  get '(page\u002F:page)', action: :index, on: :collection, as: ''\nend\n\nresources :my_resources, concerns: :paginatable\n```\n\nThis will create URLs like `\u002Fmy_resources\u002Fpage\u002F33` instead of `\u002Fmy_resources?page=33`. This is now a friendly URL, but it also has other added benefits...\n\nBecause the `page` parameter is now a URL segment, we can leverage on Rails page [caching](http:\u002F\u002Fguides.rubyonrails.org\u002Fcaching_with_rails.html#page-caching)!\n\nNOTE: 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.\n\n\n## Other Framework\u002FLibrary Support\n\n### The kaminari gem\n\nTechnically, the kaminari gem consists of 3 individual components:\n\n    kaminari-core: the core pagination logic\n    kaminari-activerecord: Active Record adapter\n    kaminari-actionview: Action View adapter\n\nSo, bundling `gem 'kaminari'` is equivalent to the following 2 lines (kaminari-core is referenced from the adapters):\n\n```ruby\ngem 'kaminari-activerecord'\ngem 'kaminari-actionview'\n```\n\n### For Other ORM Users\n\nIf you want to use other supported ORMs instead of ActiveRecord, for example Mongoid, bundle its adapter instead of kaminari-activerecord.\n\n```ruby\ngem 'kaminari-mongoid'\ngem 'kaminari-actionview'\n```\n\nKaminari currently provides adapters for the following ORMs:\n\n* Active Record: https:\u002F\u002Fgithub.com\u002Fkaminari\u002Fkaminari\u002Ftree\u002Fmaster\u002Fkaminari-activerecord  (included in this repo)\n* Mongoid: https:\u002F\u002Fgithub.com\u002Fkaminari\u002Fkaminari-mongoid\n* MongoMapper: https:\u002F\u002Fgithub.com\u002Fkaminari\u002Fkaminari-mongo_mapper\n* DataMapper: https:\u002F\u002Fgithub.com\u002Fkaminari\u002Fkaminari-data_mapper  (would not work on kaminari 1.0.x)\n\n### For Other Web Framework Users\n\nIf you want to use other web frameworks instead of Rails + Action View, for example Sinatra, bundle its adapter instead of kaminari-actionview.\n\n```ruby\ngem 'kaminari-activerecord'\ngem 'kaminari-sinatra'\n```\n\nKaminari currently provides adapters for the following web frameworks:\n\n* Action View: https:\u002F\u002Fgithub.com\u002Fkaminari\u002Fkaminari\u002Ftree\u002Fmaster\u002Fkaminari-actionview  (included in this repo)\n* Sinatra: https:\u002F\u002Fgithub.com\u002Fkaminari\u002Fkaminari-sinatra\n* Grape: https:\u002F\u002Fgithub.com\u002Fkaminari\u002Fkaminari-grape\n\n\n## For More Information\n\nCheck out Kaminari recipes on the GitHub Wiki for more advanced tips and techniques. https:\u002F\u002Fgithub.com\u002Fkaminari\u002Fkaminari\u002Fwiki\u002FKaminari-recipes\n\n\n## Questions, Feedback\n\nFeel free to message me on Github (amatsuda) or Twitter ([@a_matsuda](https:\u002F\u002Ftwitter.com\u002Fa_matsuda))  ☇☇☇  :)\n\n\n## Contributing to Kaminari\n\nFork, fix, then send a pull request.\n\nTo run the test suite locally against newest stable Rails:\n\n```sh\n% bundle install (or bundle update)\n% bundle e rake test\n```\n\nTo target the test suite against specific version of Active Record (Rails), set `RAILS_VERSION` environment variable when executing `bundle update` and `rake test`:\n\n```sh\n% RAILS_VERSION=7.2 bundle update\n% RAILS_VERSION=7.2 bundle e rake test\n```\n\n\n## Copyright\n\nCopyright (c) 2011- Akira Matsuda. See MIT-LICENSE for further details.\n","Kaminari 是一个基于Scope和Engine的分页器，专为Ruby Web应用程序设计。它提供了一个干净、强大且可定制的分页解决方案，不会污染全局对象如`Array`、`Hash`等。Kaminari支持多种ORM（如ActiveRecord、Mongoid）和Web框架（如Rails、Sinatra），并且内置了国际化支持的辅助方法，允许开发者通过覆盖模板来轻松自定义样式或行为。此外，它的API设计简洁，支持链式调用，并默认使用HTML5 `\u003Cnav>` 标签输出分页链接。适用于需要高效、灵活分页功能的各种规模的Ruby Web应用开发场景中。","2026-06-11 03:13:39","top_language"]