2014-12-03 3 views
0

У меня есть две модели. Категория и фотография. Есть много фотографий для каждой категории.Заказ на основе другого атрибута модели - Ruby

Я хочу заказать массив объектов категории таким образом, чтобы он упорядочивался по атрибуту в модели Фото. В частности, сколько раз загружается фотография.

Я пытаюсь инициировать переменную экземпляра с чем-то вроде

@category = Category.active.order('photos.qty_download DESC) 

Я бы затем использовать эту переменную экземпляра в список категорий и сколько фотографий было загружено для каждой категории

Chicago 45 
San Fran 32 
Boston 23 
etc 

Какое выражение будет работать в Rails?

Благодаря

ответ

2

Давайте предположим, что ваши модели выглядеть примерно так:

class Category < ActiveRecord::Base 
    has_many :photos 
end 

class Photo < ActiveRecord::Base 
    belongs_to :category 
end 

Давайте также предположим:

  • каждая фотография имеет qty_download поле, как вы описали в своем вопрос
  • в каждой категории имеется name Поле
  • цель состоит в том, чтобы заказать отображение категорий в соответствии с сумма всех qty_download для всех фотографий в каждой категории
  • это нормально полностью исключить категории, которые не имеют никаких связанных фотографий

с этими предположениями, вы должны быть в состоянии написать

Category. 
    joins(:photos). 
    group("categories.id, categories.name"). 
    select("categories.id, categories.name, sum(photos.qty_download) as total_downloads"). 
    order("total_downloads desc") 

Обратите внимание, что будет возвращен будет «пар которые содержат только id, name и total_downloads. Если вам нужны дополнительные поля категорий, добавьте их как в пункты group, так и в пункты select.

Update

Новые версии Postgres позволяют упростить запрос:

Category. 
    joins(:photos). 
    group("categories.id"). 
    select("categories.*, sum(photos.qty_download) as total_downloads"). 
    order("total_downloads desc") 

Обратите внимание, что в последних версиях Postgres, вы можете просто группа уникальным идентификатором - вы больше не должны группироваться по всем атрибутам, которые вы хотите включить в свой выбор. Таким образом, теперь вы можете включить все атрибуты категорий как categories.*. Я оставлю оригинал на месте, поскольку он (незначительно) более эффективен и обратно совместим со старыми версиями Postgres.

+0

И в случае, если вы хотите, чтобы все поля из категории, сделайте следующее: выберите ("категории *, SUM (фото..qty_download) AS times_downloaded ") И я думаю, что просто группировка с помощью" categories.id "должна быть достаточной – Humza

+0

По крайней мере, для Postgres, когда вы используете группу, все в предложении' select' должно либо появляться в предложении 'group by' или быть агрегированной функцией, поэтому ни одно из ваших предложений не будет работать. YMMV с другими базами данных. –

+0

вы положительны? потому что я запускал оригинал на mysql, но теперь я нахожусь в проекте rails, используя postgres, и следующее прекрасно выполняется из rails console: 'Model1.limit (1) .joins (: model2s) .group (" # {Model1.table_name} .id "). select (" # {Model1.table_name}. *, SUM (# { Model2.table_name} .id) AS mgids ")' – Humza

0
Category.includes(:photos).order(qty_download: :desc).reference(:photos) 
+0

Это не сработает, так как нет столбца 'total_downloads'. (Кроме того, вы, вероятно, имеете в виду 'ссылки' вместо' reference'.) –

+0

Крошечный комментарий о том, что он делает и почему он работает, сделает ответ еще более полезным. – Trilarion

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