计算ActiverEcord nil属性



在我的铁轨应用中,我在其中一种模型中有类似的东西

def self.calc
  columns_to_sum = "sum(price_before + price_after) as price"
  where('product.created_at >= ?', 1.month.ago.beginning_of_day).select(columns_to_sum)
end

对于某些行,我们将price_before和或price_after作为nil。这不是理想的选择,因为我想添加这两个列并将其称为price。如何在不访问数据库太多次的情况下实现这一目标?

您可以使用COALESCE确保NULL值以0为0,该值将返回第一个非NULL值:

columns_to_sum = "sum(COALESCE(price_before, 0) + COALESCE(price_after, 0)) as price"

这将计算所有产品的总和。

另一方面,如果您要做的就是有一种简单的方法来计算一种产品的价格,则可能不必这样做。然后,您可以将方法添加到Product模型

def.price
  price_before.to_i + price_after.to_i
end

这具有能够反映价格的变化(通过Price_before或Price_fter)而不必再次通过DB,因为price_beforeprice_after将默认情况下获取。

但是,如果您想例如根据您需要将该功能放置在DB中的价格中的DB中选择记录。

为此,我会调整您的范围,然后再加入它们:

def self.with_price
  columns_to_sum = "(COALESCE(price_before, 0) + COALESCE(price_after, 0)) as price"
  select(column_names, columns_to_sum)
end

这将使用其他price读取器方法返回所有记录。

和一个独立于一个范围:

def self.one_month_ago
  where('product.created_at >= ?', 1.month.ago.beginning_of_day)
end

然后可以这样使用:

Product.with_price.one_month_ago

这使您可以在击中DB之前继续修改范围,例如要获得所有价格高于x

的产品
Product.with_price.one_month_ago.where('price > 5')

如果您要获得每个单独记录的Price_before和Price_fer的总和(与整个查询结果的单个总和相反),则您想这样做:

columns_to_sum = "(coalesce(price_before, 0) + coalesce(price_after, 0)) as price"

我怀疑这就是您所追求的,因为您的查询中没有group。如果您是一个总和,则@ulferts的答案是正确的。

最新更新