Moving pagination to the Model

I’m using will_paginate in a Post class method;

def self.list(page) paginate :per_page => 10, :page => page, :include => :user end

I can happily use the method on my posts controller index action;

class PostsController < ApplicationController

def index
  @posts = Post.list(params[:page])

   respond_to do |format|
     format.html # index.html.erb
     format.js
   end
 end

But I haven’t worked out how to do it on my Users controller show
action;

class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
    @posts = @user.posts.paginate :per_page => 10,
                                  :page => params[:page]
  end

How I do I go about using the post.list class method on the post
object within the @posts variable (therefore DRYing up the pagination
and leaving it in the model)?

Neil wrote:

But I haven’t worked out how to do it on my Users controller show
action;

class UsersController < ApplicationController
> 
>   def show
>     @user = User.find(params[:id])
>     @posts = @user.posts.paginate :per_page => 10,
>                                   :page => params[:page]
>   end

How I do I go about using the post.list class method on the post
object within the @posts variable (therefore DRYing up the pagination
and leaving it in the model)?

The 1 to many association between posts can users that AR builds for you
(as an array) can be extended with :extend

check out ActiveRecord::Base::has_many() :extend

module PaginationExtension
def paginate
#your code here
end
end

class User < ActiveRecord::Base
has_many :posts, :extend PaginationExtension
end

@some_user.posts.paginate

hth

ilan

Thanks ilan. Just checked out the AP on associated extensions, but I
have one question; where should I keep the PaginationExtension module?
Posts are the only thing being paginated, so I presume I’d put the
extension at the top of the post.rb. Is this correct? Or should I create
a pagination_extension.rb?

Neil C. wrote:

Thanks ilan. Just checked out the AP on associated extensions, but I
have one question; where should I keep the PaginationExtension module?
Posts are the only thing being paginated, so I presume I’d put the
extension at the top of the post.rb. Is this correct? Or should I create
a pagination_extension.rb?

Should read ‘Just checked out the API on associated extensions’.

Neil C. wrote:

Thanks ilan. Just checked out the AP on associated extensions, but I
have one question; where should I keep the PaginationExtension module?
Posts are the only thing being paginated, so I presume I’d put the
extension at the top of the post.rb. Is this correct? Or should I create
a pagination_extension.rb?

If that is the only model using it, then it’s fine to keep it in that
model file… If on the other hand, it is to be used by more than one
model then it should be in it’s own file withing app/model or lib/

I like to embed my extension modules within the model itself as:
class Foo < ActiveRecord::Base
module SomeExtension
#
end

has_many :somethings, :extend => SomeExtension
end

hth

ilan

Neil C. wrote:

module PaginationExtension
def pagination(page)
paginate :per_page => 10,
:page => page
end
end

But I currently need to keep a class method on the Post.rb to keep it
paginating on itself;

class Post < ActiveRecord::Base

def self.pagination(page)
paginate :per_page => 10,
:page => page,
:include => :user
end

end

Any way round this?

class Post < ActiveRecord::Base

module PaginationExtension
def pagination(page, options ={})
paginate {:per_page => 10,:page => page}.merge options
end
end

has_many :whatevers, :extend => PaginationExtension

extend PaginationExtension # no reason we can’t extend it ourselves,
def pagination(page, options = {})
super(page, {:include => :user}.merge options
end

end

NOT TESTED,NOT TESTED… use at your own risk…
I believe this may be a little drier and meets your criteria…

hth

ilan

It’s all working, thanks.

Sorry if I’m missing something basic, but can I somehow reuse the
PaginationExtension on the Post.rb itself (the model being extended
through the has_many)? I was hoping to keep the pagination settings in
just one place.

The pagination_extension.rb resides in the model folder;

module PaginationExtension
def pagination(page)
paginate :per_page => 10,
:page => page
end
end

But I currently need to keep a class method on the Post.rb to keep it
paginating on itself;

class Post < ActiveRecord::Base

def self.pagination(page)
paginate :per_page => 10,
:page => page,
:include => :user
end

end

Any way round this?

Ilan B. wrote:

Neil C. wrote:

module PaginationExtension
def pagination(page)
paginate :per_page => 10,
:page => page
end
end

But I currently need to keep a class method on the Post.rb to keep it
paginating on itself;

class Post < ActiveRecord::Base

def self.pagination(page)
paginate :per_page => 10,
:page => page,
:include => :user
end

end

Any way round this?

class Post < ActiveRecord::Base

module PaginationExtension
def pagination(page, options ={})
paginate {:per_page => 10,:page => page}.merge options
end
end

has_many :whatevers, :extend => PaginationExtension

extend PaginationExtension # no reason we can’t extend it ourselves,
def pagination(page, options = {})
super(page, {:include => :user}.merge options
end

end

NOT TESTED,NOT TESTED… use at your own risk…
I believe this may be a little drier and meets your criteria…

hth

ilan

My ‘has_many :posts, :extend => PaginationExtension’ lives in the
User.rb, but the post model is the one being extended with pagination.

I tried putting ‘module PaginationExtension’ and the ‘extend
PaginationExtension’ in the Post.rb whilst keeping the ‘has_many :posts,
:extend => PaginationExtension’ in the User.rb, but I get a syntax
error;

app/models/post.rb:5: syntax error, unexpected tASSOC, expecting ‘}’
paginate {:per_page => 10, :page => page}.merge options