Заказ продуктов по количеству ассоциаций - PullRequest
4 голосов
/ 19 ноября 2009

Класс продукта

has_many :sales

end

Class Sale

belongs_to :product

end

Как получить наиболее продаваемые продукты .. (Продукт найти все .. заказать по .. ventas ..)?

Ответы [ 3 ]

15 голосов
/ 25 ноября 2009

Возможно, вы захотите поразить двух зайцев одним выстрелом (у другого - производительность), используя столбец счетного кэша в модели продукта. Например, скажем, вы совершаете продажу для продукта X. Когда эта продажа фиксируется в базе данных, она запускает обратный вызов, чтобы увеличить количество продаж для этого продукта в строке продукта в базе данных. Когда вы уничтожаете, это наоборот уменьшает количество продуктов.

Вам необходимо настроить столбец кэша в таблице продуктов. В новой миграции сделайте это:

add_column :products, :sales_count, :integer, default => 0

Product.reset_column_information

Product.all.each do |product|
  Product.update_counters(product.id, :sales_count => product.sales.length
end

Вам также необходимо внести некоторые изменения в свои модели Product и Sale, например:

class Product < ActiveRecord::Base
  has_many :sales
end

class Sale < ActiveRecord::Base
  belongs_to :product, :counter_cache => true
end

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

Надеюсь, это поможет!

5 голосов
/ 19 ноября 2009

Если вы пытаетесь упорядочить продукты по количеству связанных с ними продаж, это может быть довольно сложной проблемой, в зависимости от вашей базы данных. Гугл откопал ответ от transientink.com , но это решение лично для меня не работает. Я подозреваю, что это из-за различий в том, как PostgreSQL обрабатывает предложения GROUP BY по сравнению с MySQL.

Другой вариант - включить counter_cache в ассоциации продуктов в Sales (подробности см. По ссылке) и отсортировать по полю кэша счетчика.

Другой вариант - использовать Ruby для сортировки:

@top_products = Product.find(:all, :include => :sales).sort_by { |p| p.sales.size }

С этим связаны две основные проблемы, во-первых, вы используете веб-сервер для сортировки, что замедляет запросы (возможно, заметно, в зависимости от количества продуктов). Во-вторых, вы не можете сделать используйте опцию: limit в поисковике, поэтому, если вы хотите получить только 10 самых продаваемых продуктов, вам нужно извлечь их все из БД, отсортировать их в своем приложении и затем ограничить их впоследствии.

3 голосов
/ 19 ноября 2009

При получении Продуктов вы можете сделать:

 @products = Product.find(:all, :include => :sales, :order => "sales.value DESC")

'sales.value' может быть заменено любым значением, которое вы пытаетесь заказать, на ...


РЕДАКТИРОВАТЬ: Не обращайте внимания на остальную часть моего ответа. он не будет возвращать объекты Product в порядке убывания по стоимости продажи, он будет возвращать объекты Sales, связанные с продуктом, в порядке убывания по стоимости продажи. : P

Также вы можете указать порядок в вашей модели, например:

    Class Product
        has_many :sales, :order => 'sale_value DESC'
    end

где 'sale_value' - это то, что вы пытаетесь заказать, и, делая это таким образом, чтобы получить Продукты, вы можете просто сделать:

 @products = Product.all
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...