根据属性有条件地计算平均值

时间:2014-08-29 21:17:58

标签: ruby-on-rails activeadmin

我有一个要求,我需要根据销售的公司计算产品销售单位的平均值。从那里我将计算出售单位的百分比差异。有一个产品型号。每个产品都具有以下属性:

  • 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

2 个答案:

答案 0 :(得分: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,但出于审美原因,我更喜欢仅在结果是模型实例或实例集合时才使用范围,这不是这里的情况。)

答案 1 :(得分:1)

假设您的关联设置正确,这很容易实现。假设公司有很多产品:

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)