Forum: Ruby on Rails Pagination has many through problems

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Keith S. (Guest)
on 2007-05-10 15:22
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
Yuri L. (Guest)
on 2007-05-10 15:28
(Received via mailing list)
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.
Keith S. (Guest)
on 2007-05-10 16:20
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
Yuri L. (Guest)
on 2007-05-10 16:29
(Received via mailing list)
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  :)

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.
Keith S. (Guest)
on 2007-05-10 18:20
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-pagin...)
which suggests the use of paginating_find plugin, but i dont see how
this could be used with more than one model.

thanks
keith
(Guest)
on 2007-05-10 20:48
(Received via mailing list)
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>
This topic is locked and can not be replied to.