I have the following model:
class Section < ActiveRecord::Base
belongs_to :page
has_many :revisions, :class_name => \'SectionRevision\', :foreign_k
I understand you want to get the sections where the last revision of each section has a parent_section_id = 1;
I have a similar situation, first, this is the SQL (please think the categories as sections for you, posts as revisions and user_id as parent_section_id -sorry if I don't move the code to your need but I have to go):
SELECT categories.*, MAX(posts.id) as M
FROM `categories`
INNER JOIN `posts`
ON `posts`.`category_id` = `categories`.`id`
WHERE `posts`.`user_id` = 1
GROUP BY posts.user_id
having M = (select id from posts where category_id=categories.id order by id desc limit 1)
And this is the query in Rails:
Category.select("categories.*, MAX(posts.id) as M").joins(:posts).where(:posts => {:user_id => 1}).group("posts.user_id").having("M = (select id from posts where category_id=categories.id order by id desc limit 1)")
This works, it is ugly, I think the best way is to "cut" the query, but if you have too many sections that would be a problem while looping trough them; you can also place this query into a static method, and also, your first idea, have a revision_id inside of your sections table will help to optimize the query, but will drop normalization (sometimes it is needed), and you will have to be updating this field when a new revision is created for that section (so if you are going to be making a lot of revisions in a huge database it maybe would be a bad idea if you have a slow server...)
UPDATE I'm back hehe, I was making some tests, and check this out:
def last_revision
revisions.last
end
def self.last_sections_for(parent_section_id)
ids = Section.includes(:revisions).collect{ |c| c.last_revision.id rescue nil }.delete_if {|x| x == nil}
Section.select("sections.*, MAX(revisions.id) as M")
.joins(:revisions)
.where(:revisions => {:parent_section_id => parent_section_id})
.group("revisions.parent_section_id")
.having("M IN (?)", ids)
end
I made this query and worked with my tables (hope I named well the params, it is the same Rails query from before but I change the query in the having for optimization); watch out the group; the includes makes it optimal in large datasets, and sorry I couldn't find a way to make a relation with has_one, but I would go with this, but also reconsider the field that you mention at the beginning.