Arguments Error


#1

I’m new to rails so I apologize for my ignorance in advance… I’m
working through a tutorial here but I think it may be written for a
slightly older version of rails. Trying to make a store app.

I’m getting the following error (with application trace shown):

ArgumentError in StoreController#add_to_cart

wrong number of arguments (1 for 0)

RAILS_ROOT: script/…/config/…
Application Trace | Framework Trace | Full Trace

app/models/cart.rb:13:in initialize' app/models/cart.rb:13:innew’
app/models/cart.rb:13:in add_product' app/controllers/store_controller.rb:10:inadd_to_cart’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel/rails.rb:76:in
process' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel/rails.rb:74:insynchronize’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel/rails.rb:74:in
process' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:159:inprocess_client’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in each' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:inprocess_client’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in run' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:ininitialize’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in new' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:inrun’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in
initialize' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:innew’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in run' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:282:inrun’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:281:in
each' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:281:inrun’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:128:in run' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel/command.rb:212:inrun’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:281

Now I think this means that I have a problem with my
store_controller.rb file, which looks like this:

class StoreController < ApplicationController

def index
@products = Product.find_products_for_sale
end

def add_to_cart
@cart = find_cart
product = Product.find(params[:id])
@cart.add_product(product)
end

private
def find_cart
session[:cart] ||=Cart.new
end
end

But, I’m not sure - and it does seem a bit strange that that would be
where the error originates from as I didn’t change anything in this file
from when it was working to when I got the error.

What I did do was create a model called cart_item.rb:

class CartItem
attr_reader :product, :quantity

def initialize
@product = product
@quantity = 1
end

def increment_quantity
@quantity += 1
end

def title
@product.title
end

def price
@product.price * @quantity
end
end

And edited the cart.rb model to include a more robust add_product, it
now looks like this:

class Cart
attr_reader :items

def initialize
@items = []
end

def add_product(product)
current_item = @items.find {|item| item.product == product}
if current_item
current_item.increment_quantity
else
@items << CartItem.new(product)
end
end
end

I had it pointed out to me that the line;
current_item = @items.find {|item| item.product == product}

Should be;
current_item = @items.detect {|item| item.product == product}

But this didn’t result in any change… would REALLY appreciate any
insight!


#2

Also, my add_to_cart.rhtml view looks like this:

The shopping cart

    <% for item in @cart.items %>
  • <%= cart_item.quantity %> × <%= h(item.title) %>
  • <% end %>

#3

Your error message is:

wrong number of arguments (1 for 0)

That means that somewhere, you are calling a method that doesn’t expect
any
arguments and you are passing an argument to it. The stack trace give
you a
clue:

ArgumentError in StoreController#add_to_cart

app/models/cart.rb:13:in initialize' app/models/cart.rb:13:innew’
app/models/cart.rb:13:in add_product' app/controllers/store_controller.rb:10:inadd_to_cart’
One of the methods listed (#add_to_cart, #initialize, #new, or
#add_product)
is being called with an argument where it wasn’t expecting one.

StoreController#add_to_cart
– doesn’t expect any methods, but this is called by the Rails framework
as
an action, and Rails doesn’t pass any arguments to the action methods
Cart#add_product
– expects 1 argument, you’re calling it with 1 argument in
StoreController#add_to_cart
CartItem#new
– calls CartItem#initialize with however many arguments it was passed
– is called with 1 argument in Cart#add_product
CartItem#initialze
– expects 0 arguments, you passed 1 argument in via CartItem#new

–wpd


#4

CartItem#initialze
– expects 0 arguments, you passed 1 argument in via CartItem#new

I’m not really sure what do do with that – what should I change? Are
you saying only my CartItem#initialze is wrong?

Probably.

You could always add a parameter to your CartItem#initialize method.
I’m
not sure that you’re heading in the direction you want to be heading,
since
it appears that CartItem is not derived from ActiveRecord::Base – it’s
not
tied to a database.

You might want to go back and study Rail’s ideas regarding models, how
they
tie to database tables, and how you can initialize them.

–wpd


#5

Probably.

You could always add a parameter to your CartItem#initialize method.
I’m
not sure that you’re heading in the direction you want to be heading,
since
it appears that CartItem is not derived from ActiveRecord::Base – it’s
not
tied to a database.

You might want to go back and study Rail’s ideas regarding models, how
they
tie to database tables, and how you can initialize them.

I following along from the book DHH wrote verbatim, but it’s the second
edition. It was my understanding that having a database table for the
cart was unnecessary because it’s session data and would be avaliable
based on that user?


#6

StoreController#add_to_cart
– doesn’t expect any methods, but this is called by the Rails framework
as
an action, and Rails doesn’t pass any arguments to the action methods

Cart#add_product
– expects 1 argument, you’re calling it with 1 argument in
StoreController#add_to_cart

CartItem#new
– calls CartItem#initialize with however many arguments it was passed
– is called with 1 argument in Cart#add_product

CartItem#initialze
– expects 0 arguments, you passed 1 argument in via CartItem#new

I’m not really sure what do do with that – what should I change? Are
you saying only my CartItem#initialze is wrong?


#7

Looks like you have two open posts for the same issue… Here is the
answer from the other post…

ahhhh Sorry I see now I was thinking that the CartItem class was an
activerecord class … The issue is this:
Here you call a new object of CartItem with a product passed
@items << CartItem.new(product)
But here in the initialize you do not have a argument for
initialize…
class CartItem
attr_reader :product, :quantity
def initialize
@product = product
@quantity = 1
end
Change it to this
class CartItem
attr_reader :product, :quantity
def initialize( product )
@product = product
@quantity = 1
end

I would NEVER store the cartitem(add product to cart) in a session
object for a ecommerce application. Yes there are things that could/
should be stored in the session but not something like adding a
product to your cart… Unless you have a session replication system
for your back-end which then would store the session in either the
database or memcache anywho…


#8

Where does the cart_item come from? is that in the Store controller?
post the store controller… The view has the @cart object but also
needs the cart_item… Is that from the session?


#9

ahhhh Sorry I see now I was thinking that the CartItem class was an
activerecord class … The issue is this:
Here you call a new object of CartItem with a product passed
@items << CartItem.new(product)
But here in the initialize you do not have a argument for
initialize…
class CartItem
attr_reader :product, :quantity
def initialize
@product = product
@quantity = 1
end
Change it to this
class CartItem
attr_reader :product, :quantity
def initialize( product )
@product = product
@quantity = 1
end

Interesting, tried that and it’s spitting a "no method for cart_item
back at me:

NameError in Store#add_to_cart

Showing app/views/store/add_to_cart.rhtml where line #4 raised:

undefined local variable or method `cart_item’ for
#<#Class:0x2602924:0x26028e8>

Extracted source (around line #4):

1:

The shopping cart


2:

    3: <% for item in @cart.items %>
    4:
  • <%= cart_item.quantity %> × <%= h(item.title) %>

  • 5: <% end %>
    6:

RAILS_ROOT: script/…/config/…
Application Trace | Framework Trace | Full Trace

#{RAILS_ROOT}/app/views/store/add_to_cart.rhtml:4:in
_run_rhtml_47app47views47store47add_to_cart46rhtml' #{RAILS_ROOT}/app/views/store/add_to_cart.rhtml:3:ineach’
#{RAILS_ROOT}/app/views/store/add_to_cart.rhtml:3:in
`_run_rhtml_47app47views47store47add_to_cart46rhtml’

Any idea?


#10

I have the exact same problem.
same book.
same code.
same error.

So, how did you finally solve the problem ?

Thanks
Angel


#11

Freddy A. wrote:

Where does the cart_item come from? is that in the Store controller?
post the store controller… The view has the @cart object but also
needs the cart_item… Is that from the session?

cart_item.rb is the name of a model file, the one that starts with class
CartItem from above.

My store_controller.rb looks like this:

class StoreController < ApplicationController

def index
@products = Product.find_products_for_sale
end

def add_to_cart
@cart = find_cart
product = Product.find(params[:id])
@cart.add_product(product)
end

private
def find_cart
session[:cart] ||=Cart.new
end
end