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 end "

cart.rb has:

"class Cart

attr_reader :items attr_reader :total_price

def initialize    @items =    @total_price = 0.0 end

def add_product(product)    @items << LineItem.for_product(product)    @total_price += product.price end 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 class.

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   item end

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 end

Cheers, Louis.

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:

"<table>

<% for item in @items   @dbg = item.type   @v1=item.methods   @v2= item.instance_variables -%>   <tr>"

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.

Cheers, Louis.