Rails - depot application

I'm doing the depot example in the Agle Web development book. I'm
getting this error:

"undefined method `product' for #<BigDecimal:331ce70,'0.21E1',8(8)> "

"Extracted source (around line #9):

8: for item in @items
9: product = item.product
10: -%>
11: <tr>
12: <td><%= item.product%></td>"
this is display_cart.rhtml

line_item.rb has:

"class LineItem < ActiveRecord::Base
  belongs_to :product

  def self.for_product(product)
    item = self.new
    item.quantity = 1
    item.product = product
    item.unit_price = product.price
end "

cart.rb has:

"class Cart

attr_reader :items
attr_reader :total_price

def initialize
   @items = []
   @total_price = 0.0

def add_product(product)
   @items << LineItem.for_product(product)
   @total_price += product.price
end "

It looks like product = item.product in display_cart.rhtml is pulling
out a decimal number not a content array item. But I have no great
idea why or how to find out what is being put into @items in the cart

I haven't been able to find a Google solution to this and I dont
*think* I have any typos (the downloaded sample files from the Agiles
site at pragmaticprogrammer produces the same error)

Hi David,

Here's my guess:

"undefined method `product' for #<BigDecimal:331ce70,'0.21E1',8(8)>"
means that Ruby's trying to call the method product on a BigDecimal.
On line 9 (where the error orginates), product is being called on the
variable item. Item is an element of the @items array. @items is being
built in the add_product method of the Cart class, by calling
for_product(product) on LineItem. And this is where I think the
problem is: the last line of the for_product(product) method assigns a
price to the item variable.

Every expression in Ruby returns a value. The value returned from
performing an assignment is what the right-hand side of the expression
evaluates to. Furthermore, the last expression in a Ruby method is the
return value of that method. So, instead of returning a LineItem from
the for_product(product) method, this code is actually returning the
value of the price variable, a BigDecimal.

In short, I believe the following code will fix your problem:

def self.for_product(product)
  item = self.new
  item.quantity = 1
  item.product = product
  item.unit_price = product.price

If you find this idiom confusing (I know I do), you may use the return
keyword (although hard-core Rubyists may frown upon it!):

def self.for_product(product)
  item = self.new
  item.quantity = 1
  item.product = product
  item.unit_price = product.price
  return item


I'm still getting "undefined method `product' for #<BigDecimal:
331ce70,'0.21E1',8(8)> "

So this promising idea didnt work. I altered display_cart.rhtml thus:


for item in @items
  @dbg = item.type
  @v2= item.instance_variables

which gives:
wibble: LineItem =
instance variables: @attributes@new_record@product *
methods: before_createcreate_or_updatesave_with_validation[stuff]

So item is a LineItem class not a decimal and this looks like an
ActiveRecord class.

Which makes me wonder if this application ever worked: it's not a typo
by me I think since I downloaded the source from the website and get
the same error, but I seem to be the only one having this problem. So
I don;t know. I think I'll dump the example from the book since I seem
to be spending more time debugging it than learning Rails!

Hi David,

Do you print the class name, instance variables and methods for every
element of the @items array? I suspect that majority of the array
contains LineItem objects, but one of the elements is a BigDecimal.

You could try changing the code as I suggested above, deleting all of
the data from your database, and trying again.