Error: You have a nil object when you didn't expect it!

Hi everyone,

Very new to rails and while following the book: Beginning Ruby on
Rails E-Commerce", I'm trying ti implement a cart, but the cart
doesn't appear on the html page at all. The code for the cart in app/
views/layouts/application.rhtml:

<% if @cart %>
<div id="shopping_cart">
  <%= render :partial => "cart/cart" %>
</div>
<%= drop_receiving_element("shopping_cart", :url =>
        { :controller => "cart", :action => "add" }) %>
<% end %>

If I take out the if @cart, I get this error:

You have a nil object when you didn't expect it!
The error occurred while evaluating nil.cart_items

Extracted source (around line #7):

4:
5: <h3>Your Shopping Cart</h3>
6: <ul>
7: <% for item in @cart.cart_items %>
8: <li id="cart_item_<%= item.product.id %>">
9: <%= render :partial => "cart/item", :object => item %>
10: </li>

This code appears on app/views/cart/_cart.rhtml

Please help. Anyone?

TIA,
Elle

You have to declare the @cart variable in the controller.

You have to declare the @cart variable in the controller.

Thanks for the quick reply. Here is my cart_controller.rb:

class CartController < ApplicationController
  before_filter :initialize_cart

  def add
    params[:id].gsub!(/product_/, "")
    @product = Product.find(params[:id])

    if request.xhr?
      @item = @cart.add(params[:id])
      flash.now[:cart_notice] = "Added <em>#{@item.product.title}</

"

      render :action => "add_with_ajax"
    elsif request.post?
      @item = @cart.add(params[:id])
      flash[:cart_notice] = "Added <em>#{@item.product.title}</em>"
      redirect_to :controller => "catalog"
    else
      render
    end
  end
...

and my cart.rb model:

class Cart < ActiveRecord::Base
  has_many :cart_items
    has_many :products, :through => :cart_items

  def add(product_id)
    items = cart_items.find_all_by_product_id(product_id)
    product = Product.find(product_id)
    if items.size < 1
      ci = cart_items.create(:product_id => product_id,
                             :amount => 1,
                             :price => product.price)
    else
      ci = items.first
      ci.update_attribute(:amount, ci.amount + 1)
    end
    ci
  end
...

and my cart_item.rb model:

class CartItem < ActiveRecord::Base
  belongs_to :cart
    belongs_to :product
end

What am I doing wrong?

TIA,
Elle

Hi Elle,

What code do you have for the initialize_cart method in the
CartController?

Cheers,
Louis.