Add notes about providing an order

We got stung recently by a bug where a developer assumed that `User.per(n).page(n)` would order by `users.id`. Instead, it generates an un-ordered query, which leads to undefined ordering at the database layer.

While it's not strictly a responsibility of Kaminari to enforce this, I think reminding users in the docs that they still need to order their queries would be helpful for future developers.
This commit is contained in:
Alex Ghiculescu 2021-08-31 10:50:48 -05:00 committed by GitHub
parent 29d627dab1
commit 54d331fdf0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 11 additions and 5 deletions

View File

@ -74,6 +74,12 @@ 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:
```ruby
User.order(:name).page(7)
```
You can get page numbers or page conditions by using below methods.
```ruby
User.count #=> 1000
@ -89,14 +95,14 @@ User.page(100).out_of_range? #=> true
### The `per` Scope
To show a lot more users per each page (change the `per_page` value)
To show a lot more users per each page (change the `per` value)
```ruby
User.page(7).per(50)
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_page` without specifying the `page` number.
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:
@ -113,7 +119,7 @@ a.page(1).per(20).total_count #=> 1000
Occasionally you need to pad a number of records that is not a multiple of the page size.
```ruby
User.page(7).per(50).padding(3)
User.order(:name).page(7).per(50).padding(3)
```
Note that the `padding` scope also is not directly defined on the models.
@ -123,7 +129,7 @@ Note that the `padding` scope also is not directly defined on the models.
If for some reason you need to unscope `page` and `per` methods you can call `except(:limit, :offset)`
```ruby
users = User.page(7).per(50)
users = User.order(:name).page(7).per(50)
unpaged_users = users.except(:limit, :offset) # unpaged_users will not use the kaminari scopes
```