Custom pagination


#1

I am trying to paginate objects from a has_many/:through relationship
using Paginator.

current_user.things returns the objects that I’d like to paginate. For
testing, I tried to make it 1 item per page. I initialise the paginator
as follows:

@thing_pages = Paginator.new(self, current_user.things.count, 1,
@params[‘page’])

I don’t know how to obtain @things now though, I don’t want to be using
Things.find_all (as the wiki example shows) as I know which things I
want to be paginating (current_user.things). How can I make an array of
@things that contains the right items (e.g. starts and ends at the
correct offset)?

@things = current_user.things will obviously just return all things,
which isn’t correct. Somehow I need to select only the correct portion
of this?

Thanks.


#2

David wrote:

@things = current_user.things will obviously just return all things,
which isn’t correct. Somehow I need to select only the correct portion
of this?

Whilst browsing the Typo source I found the answer

@things = current_user.things
@thing_pages = Paginator.new(self, @things.size, 1, @params['page'])
start = @thing_pages.current.offset
stop = (@thing_pages.current.next.offset - 1) rescue things.size
@things = @things.slice(start..stop)

I especially like the rescue condition in the stop, a very neat way of
fixing the last page.


#3

The other way to do this is by passing the correct information to find.

@things = Things.find(:all, :offset=>@thing_pages.current.offset,
:limit=>@thing_pages.items_per_page)

On Monday, April 24, 2006, at 2:15 PM, David wrote:

stop = (@thing_pages.current.next.offset - 1) rescue things.size
http://lists.rubyonrails.org/mailman/listinfo/rails
_Kevin


#4

Kevin O. wrote:

The other way to do this is by passing the correct information to find.

@things = Things.find(:all, :offset=>@thing_pages.current.offset,
:limit=>@thing_pages.items_per_page)

However, surely this will return all Things, rather than just the ones
owned by the current user? That was the one thing I was trying to fix
here.


#5

Oh, yes.

add :conditions=>“user_id = #{current_user.id}”

or use this…

@things = current_user.things(:offset=>@thing_pages.current.offset,
:limit=>@thing_pages.items_per_page)

I think the second one will work, but I haven’t tried it.

Bottom line, just add the appropriate offest and limit parameters to
whichever find function you use.

On Monday, April 24, 2006, at 3:32 PM, David wrote:


Posted via http://www.ruby-forum.com/.


Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails

_Kevin


#6

Kevin O. wrote:

Oh, yes.

add :conditions=>“user_id = #{current_user.id}”

Unfortunately I can’t do this, as I’m using a has_many/:through
relationship so am not using a find() call. There is no “user_id”
column, that’s handled by a permissions table.

or use this…

@things = current_user.things(:offset=>@thing_pages.current.offset,
:limit=>@thing_pages.items_per_page)

This looks promising, but I can’t get it to work. As I already have
current_user.things, I can’t query using the class find*() methods (for
the same reason as above). I also can’t find any methods for the
array/collection that allow an offset and limit to be passed to them.

Since posting I’ve actually found this link:
http://www.bigbold.com/snippets/posts/show/389, which solves the problem
in pretty much the same way as Typo (and therefore the code I borrowed).

In this instance, I think I’ll have to make do with a few lines extra :slight_smile:

Cheers.