Как создать область для поиска «Авторов, у которых нет записей» - PullRequest
2 голосов
/ 12 октября 2010

Используя 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")
      }

Я предполагаю, что авторы с нулевыми постами просто не выбираются в третьей строке ... так в чем же решение?

Ответы [ 4 ]

1 голос
/ 12 октября 2010

Вы правы, объединение исключает всех авторов с нулевыми сообщениями, вам нужно внешнее объединение.

Я не знаю синтаксиса rails 3, но в rails 2 вы можете указать оператор joins с фрагментом SQL вместо простого использования имени отношения.
User.all(:joins => 'outer join posts on users.id = posts.user_id')
Rails 3имеют эквивалентные обозначения, но я никогда не использовал их, поэтому не знаю точного синтаксиса.Это должно быть общей идеей.

1 голос
/ 12 октября 2010

Поскольку создается внутреннее объединение SQL, он покажет результаты с записями, доступными в обеих таблицах. Поэтому попробуйте создать внешнее соединение и найти / посчитать нулевые значения в следующей таблице

попробуйте внешнее соединение

0 голосов
/ 28 декабря 2012
scope :without_posts, lambda {
    where("id NOT IN (?)", Posts.select("author_id").group("author_id") )
}

Это будет работать лучше всего, если в вашей базе данных есть индекс для author_id.

0 голосов
/ 12 октября 2010

Я не знаю много об этом, но я бы порекомендовал вам взглянуть на это Railscast

Надеюсь, это работает для вас.

...