I'm building a simple ecommerce webpage and the functionality I want to create is:
User clicks an "ADD TO CART" button in one of the products --> the ORDER is created with the user_id --> the ORDER_ITEM is created with order_id and product_id.
I want to build all the logic in OrderItem model:
class OrderItem < ApplicationRecord
belongs_to :order
belongs_to :product
before_validation :generate_order
private
def self.generate_order(user)
if Order.find_by(status: 1)
order = Order.find_by(status: 1)
else
order = Order.new(status: 1, total: 0, subtotal: 0, date: Date.today())
order.user = user
order.save!
end
return order
end
end
Basically, if there is an Order open (status = 1) then return that order and if not create one.
And in the OrderItem controller:
class OrderItemsController < ApplicationController
def create
@product = Product.find(params[:product_id])
@order = OrderItem.generate_order(current_user)
@order_item = OrderItem.new
@order_item.product = @product
@order_item.order = @order
if @order_item.save!
redirect_to cart_path
else
redirect_to root_path
end
end
def delete
end
end
Everything goes well until it arrives to the .save! point where it throws this error:
undefined method `generate_order' for #<OrderItem:0x00007fe8f77552c8>
I checked the logs and everything seems to have been created well:
>> @order_item
=> #<OrderItem id: nil, order_id: 1, product_id: 65, created_at: nil, updated_at: nil>
>> @order
=> #<Order id: 1, subtotal: 0, total: 0, date: "2021-09-05 00:00:00", user_id: 5, created_at: "2021-09-05 00:00:12", updated_at: "2021-09-05 00:00:12", status: 1>
>> @product
=> #<Product id: 65, name: "Shou Mei", description: "Sequi dolores facilis rerum quo odit veritatis ips...", price: 5893, rating: 5, user_id: 13, created_at: "2021-09-03 23:54:46", updated_at: "2021-09-03 23:54:47", availability: 2>
Why is throwing that error and how could I make it right? Thanks!
this line in your model is the problem:
before_validation :generate_order
You only have a class method self.generate_order
, but this would be looking for a instance method. Judging from the code inside self.generate_order
it doesn't seem you want that to be checked before each validation, so you can delete the line (or write an instance method that serves whatever purpose you had in mind).