Pagination has many through problems


#1

I have searched for days for an example that demonstrates what i would
like to do, and this morning i thought i’d worked it out, but
no…here’s what i have:

Controller

class ProfilesController < ApplicationController
def friends
current_user.profile.friends
end
def list_friends
@profile_pages, @profiles = paginate( friends, :per_page => 10)
end
end

Models

class Profile < ActiveRecord::Base
has_many :friendships
has_many :friends,
:through => :friendships
end

class Friendship < ActiveRecord::Base
belongs_to :profile
belongs_to :friend, :class_name => “Profile”, :foreign_key =>
“friend_id”
end

When accessing “http://localhost:3000/profiles/list_friends” i get the
error:

“#Profile:0x10ee01b4#Profile:0x10ee018c” is not a valid constant
name!

Any help gratefully recieved!!

keith


#2

Hey,

The first option to paginate expects the Symbol object which is the
name of your table, not an ActiveRecord or a list of ActiveRecord
objects.

Cheers,
Yuri

On 5/10/07, Keith S. removed_email_address@domain.invalid wrote:

current_user.profile.friends
class Profile < ActiveRecord::Base


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


Best regards,
Yuri L.


#3

Yuri L. wrote:

The first option to paginate expects the Symbol object which is the
name of your table, not an ActiveRecord or a list of ActiveRecord
objects.

Hey Yuri,

Thanks for replying so quickly!!

So does this mean i am unable to paginate a recordset that is the result
of two tables joined?

From the models you can see the only way for me to derive a list of
“friends” is from the “friendships” table.

So do i have to paginate that, and then request the “profile” for each
friendship?

thanks
keith


#4

Many thanks Yuri, i did actually have that in my application controller
from previous attempts, but you’re right it does do exactly what i’m
looking for.

For anyone looking for the solution, after including Yuri’s suggested
method in my application controller, my profiles controller eventually
looks like this:

class ProfilesController < ApplicationController
def list_friends
@friends = current_user.profile.friends
@profile_pages, @profiles = paginate_collection(@friends, :page =>
params[:page])
end
end

This does work as expected, however the scalability issue does concern
me, and i’ve been trying to absorb and understand as much as possible
about this problem.

Yuri:

Do you have any specific advice with regards to this issue?

I had read through this post
(http://www.igvita.com/blog/2006/09/10/faster-pagination-in-rails/)
which suggests the use of paginating_find plugin, but i dont see how
this could be used with more than one model.

thanks
keith


#5

Hi Keith. I know we emailed on this already, but I thought I’d post
this for others. In your situation, paginating_find works like this:

@friends = current_user.profile.friends.find(:all, :page => { :size =>
10, :current => params[:page] })

… which, of course, gets you 10 friends associated with the current
user (through the profile). Which 10 friends depends on the value of
params[:page]. So, no more loading all the friends if you only want
to show 10 of them at a time…

On May 10, 9:20 am, Keith S. removed_email_address@domain.invalid


#6

One of the options is having the following method in your
ApplicationController

def paginate_collection(collection, options = {})
default_options = {:per_page => 10, :page => params[:page]}
options = default_options.merge(options)

pages = Paginator.new(self, collection.size, options[:per_page],

options[:page])
first = pages.current.offset
last = [first + options[:per_page], collection.size].min
slice = collection[first…last]
return [pages, slice]
end

This method receives the collection as you see, and returns exactly
what paginate returns. The disadvantage of this solution is that you
have to read the whole list of objects into memory. Though, well,
your initial variant does the same :slight_smile:

Cheers.

On 5/10/07, Keith S. removed_email_address@domain.invalid wrote:

So does this mean i am unable to paginate a recordset that is the result


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


Best regards,
Yuri L.