Rails Shopping Order History

Viewed 66

I am new in Rails and I want to create shopping History. I think my association doesn't work correctly or my function current order
My model

  1. User
  2. Order
  3. Order_line_item
  4. Order_item
  5. Cart So my Db Looks like this When I click "Buy" button in cart Oder_items create in Order_line_items. For example you can order 1 item or several items. The quantity of you order save in Order Line Items. So the order_line_items save in Order. It's order history. This is how My logic work. I think so. I can see any order by id. Like this

Association

class User < ApplicationRecord
  has_many :cart_items
  has_many :order_items
  has_many :order_line_items, through: :order_items
  has_one :cart, dependent: :destroy
  has_one :order, dependent: :destroy
end
class Order < ApplicationRecord
  has_many :order_line_items
  has_many :order_items
  belongs_to :user
end
class OrderLineItem < ApplicationRecord
  has_many :order_items
  belongs_to :order
  has_one :user, through: :order
end

class OrderItem < ApplicationRecord
  belongs_to :order_line_items
  belongs_to :order
  belongs_to :product
  # has_one :user, through: :order_line_items, :source => :order

end

Application Helper

module ApplicationHelper
  
  
  def current_order_line(order_line)
    if OrderItem.find_by(order_line_id: order_line[:id]).present?
      OrderItem.find_by(order_line_id: order_line[:id])
    else 
      current_order.order_line_items || current_order.build_order_line_items
    end
  end
#I think this code doesn't work property



  def current_order
    if session[:order_id].present?
      Order.find(session[:order_id])
    else
      current_user.order || current_user.build_order
    end
  end

  def current_cart
    if session[:cart_id].present?
      Cart.find(session[:cart_id])
    else
      current_user.cart || current_user.build_cart
    end
  end
end

My Controllers

class OrdersController < ApplicationController
  def show
      @order_line_items = current_order.order_line_items
  end
end

class OrderItemsController < ApplicationController
  def create
    @order_line_items = current_order_line_items
    @order_item = @order_line_items.order_items.new(order_params)
    @order_line_items.save
    redirect_to my_orders_path
    OrderMailer.order_confirmation(current_user, @order_item).deliver_now
    flash[:success] = "Order has been confirmed"
    session[:order_id] = @order.id
    session[:user_id] = current_user.id
  def order_params
    params.require(:order_item).permit(:product_id)
  end
end

#There I need also call order_line_item to create order. I don't know how
class OrderLineItemsController < ApplicationController

  def show
     @order_items = current_order.order_items
  end
class CartsController < ApplicationController
  def show
    @cart_items = current_cart.cart_items
    @order_line_item = current_order.order_line_items.new
    @order_item = current_order_line(@order_line_item.id).order_items #I got error here
  end
Error message: 
NoMethodError in CartsController#show
undefined method `[]' for nil:NilClass

I think I made a mistake with my association and my function current_order_line doesn't work property. I will be pressure If you can help me!

Maybe I think It can be work

module ApplicationHelper
  def current_order_line
    if session[:order_line_id].present?
      OrderLineItem.find(session[:order_line_id])
    else
      current_order.order_line_items || current_order.build_order_line_items
    end
  end

class CartsController < ApplicationController
  def show
    @cart_items = current_cart.cart_items
    @order_line_item = current_order.order_line_items.new
    @order_item = current_order_line.order_items.new
  end

So then I got this error message

NoMethodError in CartsController#show
undefined method `order_items' for #<ActiveRecord::Associations::CollectionProxy []>
1 Answers

I believe that your issue might be here.

  def current_order_line
    if session[:order_line_id].present?
      OrderLineItem.find(session[:order_line_id])
    else
      current_order.order_line_items || current_order.build_order_line_items
    end
  end

If I look at the if block OrderLineItem.find(session[:order_line_id]), you are returning a OrderLineItem record.

However, the else block current_order.order_line_items || current_order.build_order_line_items does not return a OrderLineItem record. Instead, you are returning a relationship and not a single record.

When you do current_order.order_line_items, you are returning an ActiveRecord collection (not a single record). And ActiveRecord does not have a order_items method; that method is defined on OrderItem

If you want to keep the current design, what you need to do is return an OrderLineItem from current_order_line. I think the following should work (syntactically, but not sure if that makes sense in terms of the business logic):

def current_order_line
  if session[:order_line_id].present?
      OrderLineItem.find(session[:order_line_id])
    else
      if !current_order.order_line_items
         current_order.build_order_line_items
      end
      current_order.order_line_items.first
    end
end
Related