Search code examples
ruby-on-railsdeviseshopping-cart

Couldn't find Order with 'id'=2


I have recently changed my database from sqlite3 to Postgres so I could launch it to Heroku. Thus I made all the changes to my database and Gemfile, and lauched. The Heroku app is working well, but when I go back to my local branch I am triggering this error.

ActiveRecord::RecordNotFound in Devise::SessionsController#new

Couldn't find Order with 'id'=2

def current_order
   if !session[:order_id].nil?
      Order.find(session[:order_id])
   else
      Order.new
   end

Which has me confused because a) Again the Heroku app is working well. and b) Because the conditional clearly states that if order id is nil it should just Make a new order. Why would it freak out if it can't find the id? As you can see, I am using devise. Here are my cart-relevant models:

class CartsController < ApplicationController
  def show
    @order_items = current_order.order_items
  end
end


class OrderItemsController < ApplicationController
  def create
    @order = current_order
    @order_item = @order.order_items.new(order_item_params)
    @order.save
    session[:order_id] = @order.id
  end

  def update
    @order = current_order
    @order_item = @order.order_items.find(params[:id])
    @order_item.update_attributes(order_item_params)
    @order_items = @order.order_items
  end

  def destroy
    @order = current_order
    @order_item = @order.order_items.find(params[:id])
    @order_item.destroy
    @order_items = @order.order_items
  end
private
  def order_item_params
    params.require(:order_item).permit(:quantity, :subproduct_id)
  end
end

And the models:

class Order < ActiveRecord::Base
  belongs_to :order_status
  has_many :order_items
  before_create :set_order_status
  before_save :update_subtotal

  def subtotal
    order_items.collect { |oi| oi.valid? ? (oi.quantity * oi.unit_price) : 0 }.sum
  end
private
  # Sets order status of 1, in progress.
  def set_order_status
    self.order_status_id = 1
  end

  def update_subtotal
    self[:subtotal] = subtotal
  end
end




class OrderItem < ActiveRecord::Base
  belongs_to :subproduct
  belongs_to :order

  validates :quantity, presence: true, numericality: { only_integer: true, greater_than: 0 }
  validate :subproduct_present
  validate :order_present

  before_save :finalize


  # Will use the associated subproduct's price if the order item is not persisted
  def unit_price
    if persisted?
      self[:unit_price]
    else
      subproduct.price
    end
  end

  def total_price
    unit_price * quantity
  end

private
  def subproduct_present
    if subproduct.nil?
      errors.add(:subproduct, "is not valid or is not active.")
    end
  end

  def order_present
    if order.nil?
      errors.add(:order, "is not a valid order.")
    end
  end

  def finalize
    self[:unit_price] = unit_price
    self[:total_price] = quantity * self[:unit_price]
  end
end




class OrderStatus < ActiveRecord::Base
    has_many :orders
end

Thank you in advance.


Solution

  • Locally, your session still has the order_id key set to 2. That's why your code passes the if-check and gets to the Order.find call. The reason why it blows up is because the default behavior of find is now to raise ActiveRecord::RecordNotFound if it can't find a matching record.

    Now, that's probably also the correct behavior for your website. If somehow a session is tied to an order that doesn't exist, you'd be in an inconsistent state! I think you're seeing this now because you rebuilt your database, wiping the order record that your session was tied to, but haven't cleared your session. If you do so (e.g. by deleting all cookies for your localhost domain, or by closing your browser fully and re-opening it), the error will go away.