2

Rails 3 を使用すると、このスコープは期待どおりに機能します。

      scope :with_posts, lambda {
        joins(:posts).
        select("authors.*, count(posts.id) posts_count").
        group("posts.author_id").
        having("posts_count > 0")
      }

生成される SQL は次のとおりです。

SELECT authors.*, count(posts.id) posts_count FROM `authors` INNER JOIN `posts` ON `posts`.`author_id` = `author`.`id` GROUP BY posts.author_id HAVING posts_count > 0

しかし、その逆は結果を返しません。

      scope :with_posts, lambda {
        joins(:posts).
        select("authors.*, count(posts.id) posts_count").
        group("posts.author_id").
        having("posts_count < 1")
      }

投稿がゼロの著者は、単に 3 行目で選択されていないと思います...では、解決策は何ですか?

4

4 に答える 4

1

あなたは正しいです。結合は、投稿がゼロのすべての作成者を除外しています。必要なのは外部結合です。

Rails 3 の構文はわかりませんが、Rails 2 では、単純にリレーション名を使用する代わりに、SQL フラグメントを使用して結合ステートメントを指定できます。
User.all(:joins => 'outer join posts on users.id = posts.user_id')
Rails 3 には同等の表記法があるはずですが、私はそれを使用したことがないため、正確な構文はわかりません。ただし、これは一般的な考え方のはずです。

于 2010-10-12T10:53:57.837 に答える
1

Since inner joing SQL is being created it will show up the results with records available in both tables. So try creating outer join and find/count the null values in next table

try outer join

于 2010-10-12T04:45:15.700 に答える
0
scope :without_posts, lambda {
    where("id NOT IN (?)", Posts.select("author_id").group("author_id") )
}

これは、DBにauthor_idのインデックスがある場合に最適に機能します。

于 2012-12-28T17:22:15.130 に答える
0

私はこれについてあまり知りませんが、このRailscastを見ることをお勧めします

これがうまくいくことを願っています。

于 2010-10-12T05:57:14.310 に答える