Сортировка моделей ActiveRecord по атрибутам подмодели? - PullRequest
1 голос
/ 19 июля 2009

Предположим, у меня есть модель Category, которая has_many Items. Теперь я хотел бы представить таблицу категорий, отсортированных по различным атрибутам Items . Например, имейте категорию с самым дорогим предметом наверху. Или сортируйте категории по их лучшим оценкам. Или сортируйте категории по последнему элементу (т. Е. Категория с самым последним элементом будет первой).

class Category < ActiveRecord::Base
  has_many :items

  # attributes: name
end

class Item < ActiveRecord::Base
  belongs_to :category

  # attributes: price, rating, date, 
end

Какой подход лучше?

  1. Поддерживать дополнительные столбцы в модели категории для хранения атрибутов для сортировки (т. Е. Самой высокой цены товара или лучшей оценки товара в этой категории). Я делал это раньше, но это уродливо и требует обновления модели категорий каждый раз, когда Предмет меняет
  2. Какое магическое заклинание SQL в предложении порядка?
  3. Что-то еще?

Лучшее, что я могу придумать, - это SQL, для создания списка категорий, отсортированных по максимальной цене содержащихся предметов.

select categories.name, max(items.price) from categories join items group by categories.name

Не уверен, как это переводится в код Rails. Этот SQL также не работает, если я хотел, чтобы категории были отсортированы по цене самого последнего элемента. Я действительно пытаюсь сохранить это в базе данных по очевидным причинам производительности.

Ответы [ 2 ]

3 голосов
/ 09 октября 2009

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

Самый простой, вероятно, named_scopes

/ приложение / модели / category.rb

class Category < ActiveRecord::Base
  has_many :items

  # attributes: name
  named_scope :sorted_by_price, :joins => :items, :group => 'users.id', :order => "items.price DESC"    
  named_scope :sorted_by_rating, :joins => :items, :group => 'users.id', :order => "items.rating DESC"

  named_scope :active, :condition => {:active => true}


end

Тогда вы можете просто использовать Category.sorted_by_price, чтобы получить список категорий, отсортированных по цене, от самой высокой до самой низкой. Преимущества named_scopes позволяют объединять несколько похожих запросов. Используя приведенный выше код, если ваша категория имеет логическое значение с именем active. Вы могли бы использовать Category.active.sorted_by_price для получения списка активных категорий, упорядоченных по их наиболее дорогому элементу.

0 голосов
/ 19 июля 2009

Разве это не то, для чего: присоединения для?

Category.find(:all, :joins => :items, :order => 'price')

Category.find(:all, :joins => :items, :order => 'rating')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...