someoneinomaha
someoneinomaha

Reputation: 1304

How can I eager load the most recent object in a has_many relationship?

I have a rails 3 app that has models like categories and posts.

Category

has_many :posts

Post

belongs_to :category

I want to be able to display a list of categories with the most recent post listed next to it without looping through and hitting the database for each category and only pulling back one post per category.

I want to do the same thing this question poses - SQL join: selecting the last records in a one-to-many relationship - but hopefully using Active Record.

Is this a dumb thing to be doing? Should I just pull back all the posts for a category by eager loading them? I was concerned about performance, which is why I started researching this.

Upvotes: 3

Views: 199

Answers (1)

idlefingers
idlefingers

Reputation: 32047

I'm not sure if this is possible without building up the query yourself. The problem with this is that the way rails deals with eager loading isn't that good when you start getting at all conditional or trying to limit results. You can make includes nearly do what you want by creating another association:

class Category < ActiveRecord::Base
  has_one :last_post, :class_name => "Post", :foreign_key => "category_id", :order => "created_at desc"
end

Then you can use includes normally:

Category.includes(:last_post).all

But, the problem with this is that because of the sql this generates, it's still selecting all posts from the categories even though when you call category.last_post it returns only the last post. It'll generate sql similar to this:

SELECT `categories`.* FROM `categories`
SELECT `posts`.* FROM `posts` WHERE (`posts`.category_id IN (1,2)) ORDER BY created_at desc

Upvotes: 3

Related Questions