ruby-on-railsmodel-view-controllerprivate-methods

(NoMethodError) Undefined private method in model - Rails


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!


Solution

  • 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).