各セクションの最後のリビジョンがparent_section_id = 1; であるセクションを取得したいことを理解しています。
私は同様の状況を抱えています。まず、これはSQLです(カテゴリをセクション、投稿をリビジョン、user_idをparent_section_idと考えてください-必要に応じてコードを移動しない場合は申し訳ありませんが、行かなければなりません):
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)
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)")
これは機能しますが、醜いです。最善の方法はクエリを「カット」することだと思いますが、セクションが多すぎると、ループ中に問題が発生します。このクエリを静的メソッドに配置することもできます。また、最初のアイデアとして、セクション テーブル内に rev_id を含めると、クエリを最適化するのに役立ちますが、正規化が失われます (必要な場合もあります)。そのセクションの新しいリビジョンが作成されたときにこのフィールドを更新します (したがって、巨大なデータベースで多くのリビジョンを作成する場合、遅いサーバーを使用している場合は悪い考えになるかもしれません...)
更新
私は戻ってきました、私はいくつかのテストを行っていました、そしてこれをチェックしてください:
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
私はこのクエリを作成し、自分のテーブルで作業しました (params に適切な名前を付けたことを願っています。これは以前と同じ Rails クエリですが、最適化のためにクエリを変更しています); グループに気をつけてください。インクルードにより、大規模なデータセットで最適になります。申し訳ありませんが、has_one との関係を作成する方法が見つかりませんでしたが、これを使用しますが、最初に言及したフィールドも再検討してください。