为了让用户管理其产品的“实时”库存,已创建StockMovement模型/表,参考用户,库存变化(正/负)和日期.通过这种方式,我们可以根据“用户准备提供的内容”来确定特定日期的特定产品的库存.通过对单个表/模型的简单查询,我们设法获得股票的“总和”,这恰好是产品的库存.
除此之外,我们需要考虑何时下订单并确认某个产品,从而需要在一段时间内从库存中减去该项目的数量.
目前,我们使用StockMovement模型中的查询计算股票,并使用StockMovement模型中的自定义select子句手动加入受订单影响的金额,该条款已经开始变得有点过分(我们甚至不是beta).
我的问题是,你将如何实现这个Rails方式?我总是遇到这样的情况,理论上,至少考虑到关系数据库逻辑(我们使用Postgres),最好的事情是使用带有连接和计算字段的查询动态计算所有内容,但是当涉及到使用ActiveRecord实现它,除非您在模型A的select语句中重新定义该计算,否则无法在对表A的查询中引用表B中的计算列,这正是我想要避免的.
到目前为止,我目前看到的选项是:
1-保持原样:在select语句中重复计算逻辑,以访问“外部计算字段”
2-每次确认订单时在StockMovement表中创建一条记录并从那里处理所有库存(不是理想的恕我直言,因为每次在订单中修改某些东西时都需要仔细更新)
3-我无法想到的潜在魔术(和正确)解决方案……
谢谢!
解决方法
您还可以创建一个名为current_stocks的database view,每个产品只有一条记录.让该视图查询stock_movements和订单并计算当前库存,然后只需在需要该值时使用它.你甚至可以使用 make a readonly ActiveRecord class backed by the view,这样你仍然可以使用常规关联,实例方法等.再次,Rails为你提供了一种方法,使高级sql功能与你的应用程序的其余部分相得益彰.
如果你每次都在计算库存,你最终会遇到性能问题,所以你可以(1)将其设为materialized view并在后台定期刷新或(2)添加current_stock列产品并使其保持最新.我可能会选择2.
或者您可以(3)坚持使用即时计算,但添加一个starting_stocks表,为您提供“截至周日午夜时的股票”值,这样您就不必过多地计算过去.我认为这可能是最好的方法,你可以推迟实施它,直到你真正遇到问题.
如果你真的想深入研究,你可能想要了解时态数据库.两本好书是由Richard Snodgrass开发的面向时间的数据库应用程序和Tom Johnston的Bitemporal Data.前者也可以从作者的网站上免费获得PDF.我猜你现在对你来说太过分了,但是知道它仍然是件好事.