drewolson / scrivener

Pagination for the Elixir ecosystem

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

possiblity to paginate a list?

stephenmoloney opened this issue · comments

Problem:

Cannot pass a list of DB results to the Scrivener.paginate/2 function.

Description

Sometimes I find that I get a list of results from the DB using Ecto and I need to do a some operation on the list outside the realm of Ecto and Ecto Queries.
With the finalized list post processing, I still need to paginate the list but currently scrivener does not support passing in a list for pagination.

Proposed Solution:

Add ability to paginate a list.

I've started on this already and trying it out at the moment. I'd appreciate your feedback.

Thanks for writing this library BTW.

I'll need to think about this. I know that Kaminari supports this, but I'm worried about feature bloat.

sure thing. If you decide to go with it, the moduledoc would probably need a few edits aswell.

@stephenmoloney In thinking this over, I'd prefer to put it in a different library, perhaps Scrivener.List or Scrivener.Extensions. I'd be happy to link to the project from the README here and, if things to well, we could consider merging in the functionality.

Thanks for opening an issue!

Ok, that sounds fair, I like composing applications from smaller parts too.
Scrivener.List sounds good. I'll keep you posted on progress.

@drewolson

I've almost completed the ScrivenerList implementation. Only thing left is to publish it.
The deps are running off the protocol branch for now. {:scrivener, github: "drewolson/scrivener", branch: "protocol"}

I'll wait until Scrivener 2.0 is released before I publish this to hex docs and I'll bump it to 1.0 then.
If it looks okay to you, I'll make a PR request to add to link to the README at that stage. There's no rush on that.

Thanks for implementing the protocol. It seems to work nicely. The only downside I can see is that I couldn't generate docs for defimpl so I couldn't add separate docs for that module but I've added plenty in the README to make up for it.

This is close to what I was thinking, but you should only need the list.ex file, not the top-level scrivener_list.ex. I'll put together some more details tomorrow and add them here.

@drewolson
That is correct if scrivener_list is purely and exclusively for paginating a list when a Repo module has been configured. But I wanted to extend the capability a little bit further so that any list could be paginated independently of Ecto Repos and the Scrivener use Scrivener ... statement.

So in summary ScrivenerList does the following:

  1. lib/scrivener/paginater/list.ex: Extends Repo.paginate/2 by allowing a list to be passed as first arg.
  2. lib/scrivener_list.ex Provides a separate way of paginating a list independent of a Repo module but uses the familiar interface of the Scrivener project by taking advantage of %Scrivener.Config{} and returning %Scrivener.Page{}. This feature may well be useful for projects using lists sourced from other database layers other than Ecto or simply lists from json files, etc...

The paginate function is already provided directly to you on the scrivener module. It delegates to the protocol. If you only include your list.ex file, you could paginate a list like so:

Scrivener.paginate([1, 2, 3, 4, 5], %Scrivener.Config{...})

This keeps the interface consistent between protocol implementations and means that you don't need to write superfluous code (and your users don't need to use any other modules).

I'll also most likely add a new paginate clause to Scrivener that accepts a pageable and a keyword of options. This will prevent you from having to create a Scrivener.Config directly. This means you'd also be able to call paginate like so (without any extra code):

Scrivener.paginate([1, 2, 3, 4, 5], page_size: 2, page: 1)

One last thing: I've update my work in progress branch name from protocol to v2. Please update your dependency as necessary.

@drewolson
Perfect, these changes will work. I didn't realize that Scrivener.paginate/2 had changed to delegate to Scrivener.Paginater.paginate/2.
The only thing missing then is like you said the ability to pass a keyword opts or map of options. I think this feature would be a nice addition. 🙏
So I'll go ahead and remove my scrivener_list.ex top level file. The readme can act as docs.

all updated now

The readme is written on the presumption that the ability to pass keyword or map options to Scrivener.paginate/2. I've adding Pending notices for those comments. And I've commented out the tests for that feature too.

I'll just remove those comments later if that feature doesn't go ahead.

I saw your changes on v2 👍 and so I reintroduced the tests for keyword and map options and uncommented the pending notices. All tests passed. 🎉