Rails ActiveRecord: выбор сообщений без комментариев - PullRequest
3 голосов
/ 06 июня 2010

У меня есть таблица комментариев и таблица сообщений, где в сообщении много комментариев, а комментарий принадлежит сообщению (то есть в таблице указан post_id).

Как я могу эффективно выбрать последние десять сообщений, которые НЕ имеют комментариев. Кажется, я не могу этого сделать без предварительного выбора всех сообщений и проверки каждого на 0 комментариев.

Заранее спасибо за любую помощь.

1007 * Натан *

Ответы [ 6 ]

8 голосов
/ 06 июня 2010

Вы можете сделать

Post.find(:all, :include => :comments, :conditions => "comments.id is null", :limit => 10, :order => "created_at desc")
3 голосов
/ 06 июня 2010

Можно добавить кэш счетчика для модели Comment и пару именованных областей действия для модели Post. Что-то вроде:

class Post < ActiveRecord::Base
  has_many :comments

  named_scope :recent, :limit => 10, :order => 'created_at DESC'
  named_scope :uncommented, :conditions => { :comments_count => 0 }
end

class Comment < ActiveRecord::Base
  belongs_to :post, :counter_cache => true
end

Если вы используете Rails 3, то синтаксис именованной области действия немного отличается:

class Post < ActiveRecord::Base
  has_many :comments

  scope :recent, limit(10).order('posts.created_at DESC')
  scope :uncommented, where(:comments_count => 0)
end

Теперь вы можете находить посты без комментариев, объединяя названные области:

@uncommented = Post.recent.uncommented

Если вы хотите получить все сообщения без каких-либо комментариев (т. Е. Не только десять самых последних сообщений), тогда это будет:

@uncommented = Post.uncommented

- Возможно, вы заметили, что в примере с Rails 3 я включил имя таблицы posts в область действия :recent. Это хорошая практика, чтобы избежать двусмысленных имен столбцов в запросах SQL, если две таблицы имеют одинаковое имя столбца. Этот Railscast объясняет больше.

1 голос
/ 06 июня 2010

Добавьте столбец comments_count в таблицу сообщений и дайте миграции обновить счетчики. Теперь Rails будет автоматически обновлять ваш счетчик, если вы введете :counter_cache => true для ассоциации. Сейчас очень легко выбрать последние 10 сообщений:

Post.find_all_by_comments_count 0, :order => 'created_at DESC', :limit => 10

Ссылка на документацию: http://rails.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#M001318

0 голосов
/ 12 августа 2013

Post.includes (: комментарии) .where ("comments.id is null")

0 голосов
/ 06 июня 2010

Вам нужно левое внешнее соединение:

Post.all :joins => "left outer join comments on posts.id = comments.post_id", :conditions => "comments.id is null", :limit => 10, :order => 'created at desc'

Эта ссылка должна помочь вам понять различные типы соединений SQL: http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

0 голосов
/ 06 июня 2010

Вы должны добавить условие как-то так:

:conditions => '(SELECT count(*) FROM comments WHERE post_id = #{id}) = 0'

Я не эксперт по SQL, так что, может быть, есть что-то вроде ключевого слова EMPTY или около того.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...