2014-08-29 2 views
0

У меня есть требование, когда мне нужно рассчитать среднее количество единиц, проданных для продукта, на основе компании, в которой они были проданы. Оттуда я буду рассчитывать процентную разницу с проданной единицей. В нем есть одна модель с продуктами. Каждый продукт имеет атрибуты:Вычислить среднее условно на основе атрибута

  • PRODUCT_NAME
  • unit_sold
  • компания

Есть много компаний.

Этот код работает для расчета среднего значения по всем записям, однако я бы хотел рассчитать среднее условие, основанное на атрибуте «компания».

def average_UnitSold 
    self.class.average(:unit_sold) 
    end 

def averagechange_UnitSold 
     (self.unit_sold - average_UnitSold)/average_UnitSold * 100 
    end 

я придумал, но это не работает:

def average_UnitSold 
     self.class.sum(:unit_sold), :conditions => "company = self.company"))/:unit_sold 
    end 

Любые идеи?

В другом примечании, является более жизнеспособным подходом, где хранятся все эти средние значения и только обновление их на ежедневной основе более эффективно?

На основании ответа, я уже реализовал этот код, и это похоже на работу:

def self.average_unit_sold(company) 
    where(company: company).average(:unit_sold) 
end 

def average_unit_sold 
      self.class.average_unit_sold(self.company) 
     end 

def averagechange_UnitSold 
     (self.unit_sold - average_unit_sold)/average_unit_sold * 100 
    end 
+0

У вас есть какая-либо ассоциация между вашим модели? Это сделало бы вещи удивительно простыми. –

+0

Эй есть только одна модель для этого – bnussey

+0

нет модели 'Company'? Странно. Структура данных подсказывает это. @infused показал, что я имею в виду в его ответе. –

ответ

1

Это очень странно, что вы делаете это в методе экземпляра, так как результат не на самом деле имеют какое-либо отношение к конкретному экземпляру. Вместо этого, определить метод класса:

class Product < ActiveRecord::Base 
    # `self.average_unit_sold` is a class method that takes `company` as an 
    # argument and executes an SQL query like this (where 'some_company' is the 
    # company given in the argument): 
    # 
    #  SELECT AVG(products.unit_sold) FROM products 
    #  WHERE products.company = 'some_company' 
    # 
    def self.average_unit_sold(company) 
    where(company: company).average(:unit_sold) 
    end 
end 

# ...then... 
Product.average_unit_sold(some_company) 

Если вы действительно хотите иметь метод экземпляра, вы можете добавить один (но сохранить логику в методе класса):

# `average_unit_sold` is an instance method that takes the value of the 
# instance's own `company` attribute and calls `Product.average_unit_sold`: 
def average_unit_sold 
    self.class.average_unit_sold(self.company) 
end 

(Это также может быть scope, но по эстетическим соображениям я предпочитаю использовать области только тогда, когда результатом является экземпляр модели или коллекция экземпляров, что здесь не так.)

+0

Спасибо за ваш ответ, я добавил в код выше и, похоже, работает .. Не могли бы вы объяснить, почему?Я новичок в ruby ​​ – bnussey

+0

@bnussey Это довольно простой способ, и я не думаю, что могу объяснить его лучше, чем документация Rails. Прочитайте [Основы активной записи] (http://guides.rubyonrails.org/active_record_basics.html) для обзора того, как работают модели Rails, а затем [Интерфейс запросов активной записи] (http://guides.rubyonrails.org/active_record_querying .html), чтобы понять, как работают запросы к базе данных в Rails. В конце концов вы захотите прочитать все [Rails Guides] (http://guides.rubyonrails.org/), возможно, скорее раньше, чем позже. –

+0

Удивительная благодарность за это и за добавление дальнейшего объяснения в ответ. – bnussey

1

Предполагая, что ваши ассоциации настроены правильно я s довольно легко выполнить. Так если предположить, что компания имеет много продуктов:

class Company < ActiveRecord::Base 
    has_many :products 
end 

class Product < ActiveRecord::Base 
    belongs_to :company 
end 

Средних проданные единиц для всех компаний:

Product.average(:unit_sold) 

Средних проданных единицы для одной компании:

company = Company.find(1) 
company.products.average(:unit_sold) 
+0

Эй, @infused данные не создаются в приложении, а поступают из внешнего источника, поэтому эти ассоциации не были настроены. В чем преимущество этого? – bnussey

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