I am developing a rental marketplace application with Rails 5. It has a quite simple structure with users, products and orders, with the products belonging to users, who actually create them.
In order to let the users manage a "live" stock of their products, a StockMovement model/table has been created, with reference to the user, and the stock change (positive/negative) and a date. This way, we can determine the stock of a certain product for a specific date, in terms of "what the user is prepared to offer". With a simple query to a single table/model we manage to get the "sum" of the stocks, which happens to be the stock of the product.
Apart from that, we need to consider when an order is placed and confirmed for a certain product, resulting in the need of substracting an amount of that item from the stock for a period of time.
Currently, we calculate the stock with the query in the StockMovement model, and manually joining the amounts affected by orders, using a custom select clause in the StockMovement model, which is beginning to feel overkill already (we're not even beta).
My question is, how would you implement this the Rails way? I've always had trouble with such situations where, theoretically, at least with relational db logic in mind (we use Postgres), the optimal thing is to calculate everything on the fly using queries with joins and calculated fields, but when it comes to implementing it with ActiveRecord, there is no way of referencing a calculated column in table B in a query to table A, unless you re-define that calculation in a select statement in model A, which is what I'm trying to avoid.
So far, my options as I currently see are:
1- Keep things the way they are: repeat the calculation logic in the select statement in order to access "foreign calculated fields"
2- Create a record in the StockMovement table every time an order is confirmed and handle all stock from there (not desirable IMHO, as it needs to be carefully updated every single time something is modified in the orders)
3- The potential magic (and right) solution I haven't been able to think of...
Thank you!