2015-05-25 2 views
0

я работаю над проектом, который имеет очень похожую дилемму для этого спросить: Ordering by number of associations in common (Rails)Сортировка по количеству ассоциаций в общих даже если ни один (рельсам)

автор вопроса упомянутого спросить (Неон) пишет,

ПРЕДПОСЫЛКИ: У меня есть сообщения и пользователи, и у обоих есть много сообществ.

ЦЕЛЬ: Для любого пользователя я хотел бы вернуть коллекцию сообщений, по заказу, сколько общин пост имеет общего с пользователя (сообщения с большим количеством общин в-общий быть выше)

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

РАСШИРЕННОЙ ЦЕЛИ: Результат должен быть объектом AREL с всех сообщениями упорядоченных по количеству общих общин, в том числе сообщений с нулевыми общинами в общем с пользователем (сообщения с большим количеством общин в-общего быть выше).

ответ

1

Если вам нужно включить сообщения с нулевыми общими сообществами, вы можете использовать LEFT JOIN. Для того, чтобы дезинфицировать параметры, которые передаются в join состоянии, мы можем определить это в методе класса, так что метод sanitize_sql_array доступен:

# Post class 
def self.community_counts(current_user) 
    current_user.posts.joins(sanitize_sql_array(["LEFT JOIN community_posts ON community_posts.post_id = posts.id AND community_posts.community_id IN (?)", current_user.community_ids])).select("posts.*, COUNT(DISTINCT community_posts.community_id) AS community_count").group("posts.id").order("community_count DESC") 
end 

Дополнительная информация

INNER JOIN возвращает пересечение между двумя таблицами. A LEFT JOIN возвращает все строки из левой таблицы (в этом случае posts) и возвращает соответствующие строки из правой таблицы (community_posts), но также возвращает NULL с правой стороны, когда нет соответствия (сообщения без сообществ, которые соответствуют пользовательским сообщества). См. this answer для иллюстрации.

Насколько я знаю, Rails не предоставляет никаких вспомогательных методов для создания LEFT JOIN. Мы должны выписать SQL для них.

LEFT JOIN такое же как LEFT OUTER JOIN (more info).

+0

Woah neat - мне нужно попробовать свое решение, прежде чем я правильно помету ваш ответ, но не могли бы вы объяснить, как «LEFT JOIN» отличается от 'JOIN'? И вам неизвестно, есть ли какие-либо рельсы, которые убеждают методы делать «LEFT JOIN»? – BananaNeil

+0

Кроме того, «LEFT JOIN» отличается от «LEFT OUTER JOIN»? – BananaNeil

+0

Похоже, ваш ответ работает отлично. Спасибо за помощь! Если у вас есть средства, было бы замечательно, если бы вы могли расширить свой ответ, чтобы ответить на мои последние два комментария. – BananaNeil