2016-04-18 4 views
1

Учитывая класс, я хотел бы вернуть все объекты (index), отсортированные по количеству ассоциаций, которые у них есть с определенным атрибутом.Соотношение подсчетов по значению атрибута

Например, скажем User has_many :fish я хочу, чтобы показать список всех пользователей и заказать их по сколько :fish они имеют, что есть color: :red (Если предположить, что это перечисление/целое значение)

Пользователей с 0 красной рыбой, или 0 рыб вообще, все равно должны быть показаны на столе, но отсортированы снизу.

-- User -- | - # of fish - | - # of red fish - 
    2  |  10  |  10 
    5  |  25  |   7 
    6  |  11  |   6 
    7  |  18  |   5 
    1  |  27  |   4 
    3  |  23  |   1 
    4  |  3  |   0 
    8  |  0  |   0 

До сих пор мне удалось отсортировать пользователей по количеству рыб они, используя left_join драгоценный камень, но у меня возникают проблемы сортировки атрибутом на этой модели.

Это, как я сортировка по количеству рыбы:

@users = User.left_join(:fish).group("user.id").order("count(user.id) desc")

Любая помощь будет удивительным! Я предполагаю, что это тривиально, но я также показываю эти данные, поэтому любой способ сохранить эти данные временно также будет потрясающим! (Я предполагаю, что с помощью select и установки счетчиков в качестве переменных)

EDIT:

Решение, благодаря Энтони Е.

@users = User.select("users.*") 
      .joins("LEFT JOIN fishes ON fishes.user_id = users.id") 
      .where(fishes: { color: Fish.colors[:red] }) 
      .group("users.id").order("COUNT(fishes.id) DESC") 
      .page(params[:page]) // To work with Kaminari/pagination 

ответ

1

Как насчет:

User.select("user.*, COUNT(fish.id) AS fish_count") 
     .joins(:fish) 
     .where(fish: { color: "red" }) 
     .group("user.id") 
     .order("fish_count DESC") 

Выгода заключается в том, что вы можете вызвать fish_count на каждый объект в возвращенной возвращенной коллекции, поскольку она находится в вашем select

EDIT

Чтобы включить пользователей с 0 рыбы, использовать LEFT JOIN и изменить положение, где:

User.select("user.*, COUNT(fish.id) AS fish_count") 
     .joins("LEFT JOIN ON fish.user_id = user.id") 
     .where("fish.color = 'red' OR fish.color IS NULL") 
     .group("user.id") 
     .order("fish_count DESC") 
+0

Это поднимает 'PG :: UndefinedTable' ошибка в том случае, когда у пользователя 0 рыб. (Я считаю, что это происходит из-за 'count' в' select') – Rockster160

+0

Это странно, пользователи без рыбы должны быть исключены с помощью предложения 'joins'. Ваши имена таблиц - 'user' и' fish', правильно? Если вы добавили '.where.not (fish: {user_id: nil})' после функции 'joins (: fish)', проблема сохраняется? –

+0

Исключая их, было бы проблемой, независимо от того, что все еще должно показать всех Пользователей, независимо от их количества рыб, просто отсортированных по их количеству рыбы. (Вот почему я использовал 'left_join', а не просто' joins'), хотя вы правы. Я не уверен, почему это поднимает проблему. – Rockster160

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