2014-06-13 3 views
0

Пользователи have_many posts.Пользователь has_many сообщений. Получить всех пользователей, у которых есть как минимум 1 сообщение

В представлении я хочу получить алфавитный список всех пользователей, имеющих хотя бы 1 сообщение. Вот как я это делаю сейчас. Есть ли способ сделать все это в одной строке/используя лучшие соглашения Rails ActiveRecord?

@users.order("name ASC").each do |user| 
    if user.posts > 0 
    ... 
    end 
end 
+0

Вы можете взглянуть на это и изменить его соответственно: http://stackoverflow.com/questions/4314987/find-all-posts-with-more-than-a-defined-number-of-comments –

ответ

0

Мы можем получить все идентификаторы пользователей, которые имеют по крайней мере одно сообщение, используя это.

Post.uniq.pluck(:user_id); 

И затем мы можем получить все данные пользователя следующим образом.

User.order(:name).find(Post.uniq.pluck(:user_id)); 
+1

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

3

Ваше текущее решение неплохое (это единственный запрос), но его можно улучшить.

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

User.where('posts_count > 0').order('name ASC') 

здесь находятся документы на :counter_cache (taken from here):

: counter_cache

кэшей количество принадлежащих объектов на ассоциированном классе через использование increment_counter и decment_counter. Счетчик кеша увеличивается, когда объект этого класса создается и уменьшается при его уничтожении. Для этого требуется, чтобы столбец с именем # {table_name} _count (например, comment_count для принадлежащего класса Comment) использовался в ассоциированном классе (например, класс Post) - это миграция для # {table_name} _count создается в ассоциированном class (такой, что Post.comments_count вернет отсчет кеширования, см. примечание ниже). Вы также можете указать столбец кэша настраиваемых столбцов, указав вместо этого значение столбца вместо значения true/false (например, counter_cache:: my_custom_counter.) Примечание. Указание кеша-счетчика добавит его в список атрибутов readonly с этой моделью, используя attr_readonly.

0

User.joins(:posts).order('users.name asc') будет выполнять внутреннее соединение, как описано в документации here. Кэш-счетчик также не является плохим решением.

+0

Использование соединения - отличная идея, если вы планируете использовать сообщения, связанные с пользователями в одном и том же действии. –

+0

Ну, нет, если вы хотите действительно получить сообщения, вам нужно 'includes'. 'joins' полезен, если вы хотите отфильтровать что-то делать с сообщениями позже в цепочке областей видимости, или, если вы здесь хотите фильтровать их простое существование. – histocrat

Смежные вопросы