繁体   English   中英

按虚拟属性而不是数据库字段过滤记录?

[英]Filter records by virtual attribute rather than database field?

我在我的User模型中使用此功能来填充表单中的选择框:

def outstanding_invoices
  invoices.to_a.select { |invoice| invoice.balance < 0 }
end

问题是, balance不是数据库字段,而是计算某些东西的方法。

因此,生成选择框需要大量的SQL查询,因为上面的函数会迭代user拥有的每个invoice

是否有更快的方法来生成选择框,理想情况下只使用一个SQL查询?

一个简单的替代方案可能是将每张invoicebalance存储在数据库中,但我不知道这样做是因为我想将数据库保持在最低限度。

谢谢你的帮助。

根据使用计算货币值的经验,在很多情况下,将计算值与用于计算该值的参数一起存储是有意义的 - 这样您就可以针对计算值运行查询,但您还可以追溯到如何计算价值。

在您的发票示例中,我建议您在Payment模式中实施after_save回调。 例如:

class Payment < ActiveRecord::Base
  belongs_to :invoice

  def after_save
    invoice.update_balance
  end
end

class Invoice
  has_many :payments

  def self.with_open_balance
    where("current_balance > 0")
  end

  def update_balance
    update_attributes(:current_balance => balance)
  end

  def balance
    invoiced_amount - payments.sum(:amount)
  end
end

通过这种方法,您现在可以调用customer.invoices.with_open_balance来获取该customer.invoices.with_open_balance所有未结发票。 每当保存付款时,付款所属的发票将重新计算其余额并将该计算值存储在同一数据库事务中,从而确保一致性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM