Переменные класса создаются (обновляются) для каждого нового экземпляра - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть два класса Категория и order_item , где order_item принадлежит_to категория.

Я хочу добавить уникальную 'категорию' элементы переменной класса, которая является массивом «категорий» и представлена ​​переменной класса массива @@ CategoriesList , каждый раз, когда среди переменных экземпляра обнаруживается новая категория.

Это то, что я пробовал.

class OrderItemsController < ApplicationController

@@categoriesList = []

def create
    @order_item = OrderItem.new(order_item_params)
    if @order_item.save

      @total = @order_item.order.total
      @orderItemCategory = @order_item.category

      if @orderItemCategory.set?
        if !(@@categoriesList.include? @orderItemCategory)
            @total += @orderItemCategory.price
            @@categoriesList.push(@orderItemCategory)
        end
........
........
end

Код Объяснение:

Мне не нужна цена следующего экземпляра order_item для учета, если уже учтена цена предыдущего элемента order_item, который относится к цене той же категории.

Например: Яйцо и Молоко оба относятся к Combo-1. Поэтому я просто хочу учесть цену Combo-1 один раз, а не для каждого экземпляра order_item, то есть яйца и молока, которые удвоили бы общую сумму.

То, что я пробовал:

I pu sh название категории для order_item после того, как его цена была учтена. И когда был создан следующий элемент order_item, я проверил, записана ли уже цена этой категории order_item, проверив ее в текущей переменной класса @@ CategoriesList .

Проблема: В каждом случае, когда я проверяю переменную класса @@ CategoriesList , он возвращает пустой список массивов, и никакие предыдущие записи, которые были помещены в этот массив, не отображаются.

Я хочу что-то как переменная stati c в java, где каждый экземпляр класса использует одну и ту же переменную без фактического обновления данных в переменной для каждого экземпляра.

1 Ответ

0 голосов
/ 14 апреля 2020

Вам не нужны переменные класса в значительной степени, поскольку они не являются поточно-ориентированными или фактически постоянными в запросах, что действительно применимо практически к любому языку программирования. Каждый раз, когда код перезагружается, переменная класса сбрасывается.

То, что вы пытаетесь сделать, действительно можно сделать, правильно смоделировав домен. В случае системы контроля это было сделано уже миллиард раз, и общий шаблон:

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 %>
...