Вам не нужны переменные класса в значительной степени, поскольку они не являются поточно-ориентированными или фактически постоянными в запросах, что действительно применимо практически к любому языку программирования. Каждый раз, когда код перезагружается, переменная класса сбрасывается.
То, что вы пытаетесь сделать, действительно можно сделать, правильно смоделировав домен. В случае системы контроля это было сделано уже миллиард раз, и общий шаблон:
class Order < ApplicationRecord
has_many :line_items
has_many :products, through: :line_items
end
# rails g model line_item quantity:decimal unit_price:decimal order:belongs_to product:belongs_to
class LineItem < ApplicationRecord
belongs_to :order
belongs_to :product
end
class Product < ApplicationRecord
has_many :line_items
has_many :orders, through: :line_items
end
В таблице позиций, которая представляет фактическую строку в форме заказа, вы сохраняете, к какому заказу относится элемент. до, количество и цена за единицу на момент покупки. Чтобы подсчитать заказ, вы суммируете позиции:
class LineItem < ApplicationRecord
# ...
def net
quantity * unit_price
end
end
class Order < ApplicationRecord
# ...
def net
line_items.sum(&:net)
end
end
Так что тогда вы можете просто позвонить order.net
, и он даст вам сумму net. Я понятия не имею, куда вы идете с этим беспорядком категорий, но если бы мы посмотрели цену здесь, перейдя к продукту, мы не смогли бы учесть прошлые транзакции, если цены не будут полностью установлены c.
Вот как бы вы справились с созданием позиций:
resources :orders do
resources :line_items
end
class LineItemsController < ApplicationController
before_action :set_order
# GET /orders/1/line_items
def new
@line_item = @order.line_items.new
@products = Product.all
end
# POST /orders/1/line_items
def create
@line_item = @order.line_items.new(line_item_params) do |items|
items.unit_price = li.product.price # stores the price at time of purchase
end
if @line_item.save
redirect_to @order
else
@products = Product.all
render :new
end
end
# ...
private
def line_item_params
params.require(:line_item)
.permit(:quantity, :product_id)
end
def set_order
@order = Order.find(params[:order_id])
end
end
<%= form_with(model: [@order, @line_item], local: true) do |f| %>
<div class="field">
<%= f.label :product_id %>
<%= f.collection_select :product_id, @products, :id, :name %>
</div>
<div class="field">
<%= f.label :quantity %>
<%= f.number_field :quantity %>
</div>
<%= f.submit %>
<% end %>