views:

289

answers:

3

Is there a shortcut for giving a limit and order when accessing a has_many relation in an ActiveRecord model?

For example, here's what I'd like to express:

@user.posts(:limit => 5, :order => "title")

As opposed to the longer version:

Post.find(:all, :limit => 5, :order => "title", :conditions => ['user_id = ?', @user.id])

I know you can specify it directly in the has_many relationship, but is there a way to do it on the fly, such as showing 10 posts on one page, but only 3 on another?

+6  A: 

I have something similar in a blog model:

  has_many :posts, :class_name => "BlogPost", :foreign_key => "owner_id",
    :order => "items.published_at desc", :include => [:creator] do
      def recent(limit=3)
        find(:all, :limit => limit, :order => "items.published_at desc")
      end
  end

Usage:

Blog.posts.recent

or

Blog.posts.recent(5)
Dustin
+1  A: 

You can use Ryan Daigle's utility_scopes. After installation (it's a gem) you will get some new useful scopes such as:

@user.posts.ordered('title ASC').limited(5)

You can even set default order and limit for any model.

Milan Novota
+3  A: 

You can do it using a named scope on the post model:

class Post < ActiveRecord::Base
  named_scope :limited, lambda {|*num| {:limit => num.empty? ? DEFAULT_LIMIT : num.first}}
end

This is essentially similar to utility_scopes, as reported by @Milan, except you do it piece meal, only where you need to do it.

François Beausoleil