0
\$\begingroup\$

I've the following scenario: the user clicks the "Sales" button which redirects to the creation view of the Shopping Cart. Then, the user enters the EAN code and the Quantity, presses "Add" and the view sends an AJAX request to the add_item method of the SalesController. Then, the controller searches the data for the EAN given and a row is added to the table via JS. Also, an Item object is added to an Items array in the Session object. I decided to persist this data in the Session because I want to save all the objects (Sale and SaleItems) at the same time when the user presses "Save".

SalesController

class SalesController < ApplicationController
  def new
    @sale = Sale.new
    @sale.saleItems.build
    cart_item
  end

  def create
    @sale = Sale.new()
    if(@sale.grabar(session[:items]))
      session[:items] = []
      redirect_to new_sale_url
    end
  end



  def add_item

      @item = SaleItem.new
      @item_atributos = Material.price(params[:item][:gtin]).first
      @item.quantity = params[:item][:cantidad]
      @item.material_id = @item_atributos.id
      @item.unit_price = @item_atributos.unit_price
      @item.total = @item.quantity*@item_atributos.unit_price
      cart_item
      session[:items] << @item



      respond_to do |format|
        format.js #{render :json => @precio}
      end

  end

  private
    def sales_params
      params.require(:sale).permit(:total,saleItems_attributes:[:sale_id,:material_id,:unit_price,
        :quantity,:total])
    end


end

Sale model

    class Sale < ApplicationRecord
      has_many :saleItems
      accepts_nested_attributes_for :saleItems

      def total(array)
        @total = 0
        array.map { |item| item["total"]}.sum
      end

      def grabar (array)
        ActiveRecord::Base.transaction do
          @sale = Sale.create!(total: total(array))
          array.each do |item|
            item[:sale_id] = @sale.id
            SaleItem.create!(item)
          end
        end
      end
    end

new.html.erb

<h3><%= yield(:title_text) %></h3>

<table id="tabla" class="table table-bordered">
  <thead>
    <tr>
      <th scope="col">Producto</th>
      <th scope="col">Cantidad</th>
      <th scope="col">Precio unitario</th>
      <th scope="col">Subtotal</th>
      <th scope="col">Acciones</th>
    </tr>
  </thead>
  <tbody>
  </tbody>
</table>

<div style="position: fixed;left: 0;bottom: 0;width: 100%;text-align:center">
<%= form_tag(add_item_path(:gtin,:cantidad), method: 'get', remote: true) do %>
<div style="display-block:inline">
  <%= label_tag(:gtin, 'Código') %>
  <%= text_field_tag "item[gtin]" %>
  <%= text_field_tag "item[cantidad]" %>
  <%= submit_tag("Agregar", :class => "btn btn-primary") %>
  <%= link_to "Vender", sales_path, class:"btn btn-success", :method => :post %>
<% end %>
</div>
</div>

add_item.js.erb

$("#tabla tbody").append("<%= j render partial: 'saleItem', locals: {item: @item, atributos: @item_atributos} %>");

$("#tabla").on('click', '#borrar', function () {
  $(this).closest('tr').remove();
  });

_saleItem.html.erb

<tr>
  <th scope="row">
    <%= @item_atributos.description %>
  </th>
  <td><%= @item.quantity %></td>
  <td><%= @item_atributos.unit_price %></td>
    <td><%= @item.quantity * @item_atributos.unit_price%></td>
  <td>
    <button type="button" id="borrar" class="btn btn-danger">Borrar</button>
  </td>
</tr>

The code works well but my questions aims at code quality and design. I want a solution based on the OOP. Have I used the ROR tools well? Where should I improve my design? For example, I'm not using the strong parameters. The DB transaction was developed manually looping through Item objects. I feel that this solution doesn't use all the ROR features that makes coding easier!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.