nil can't be coerced into BigDecimal

hi guys im playing with RoR with the environment of rails 3 ruby 1.9 i got stuck in

nil can't be coerced into BigDecimal

error

i need to get the total cost of the products inside the cart i know where the problem is(i think) but i almost did every thing cart/show.html.rb

<div class="cart_title" >Your Cart</div>     <table>         <% for item in @cart.line_items %>     <tr>         <td><%= item.quantity %>&times;</td>         <td><%= item.product.title %></td>     <td class="item_price" ><%= number_to_currency(item.total_price) %></td>     </tr>     <% end %>         <tr class="total_line" >         <td colspan="2" >Total</td>         <td class="total_cell" ><%= number_to_currency(@cart.total_price) %></td>     </tr>     </table>         <%= button_to 'Empty cart', @cart, :method => :delete,         :confirm => 'Are you sure?' %>

model/line_item.rb

  def total_price     line_items.to_a.sum { |item| item.total_price }   end model/cart.rb

def total_price     product.price * quantity   end my second option is

def total_price      if product.price        product.price * quantity      else        product.price = "0.0".to_d      end    end but still this wont work

thanks more power to us!

hi guys im playing with RoR with the environment of rails 3 ruby 1.9 i

got stuck in

nil can’t be coerced into BigDecimal

error

i need to get the total cost of the products inside the cart i know

where the problem is(i think) but i almost did every thing

cart/show.html.rb

Your Cart
<table>

    <% for item in @cart.line_items %>

<tr>

    <td><%= item.quantity %>&times;</td>

    <td><%= item.product.title %></td>

<td class="item_price" ><%= number_to_currency(item.total_price)

%>

</tr>

<% end %>

    <tr class="total_line" >

    <td colspan="2" >Total</td>

    <td class="total_cell" ><%=

number_to_currency(@cart.total_price) %>

</tr>

</table>

    <%= button_to 'Empty cart', @cart, :method => :delete,

    :confirm => 'Are you sure?' %>

model/line_item.rb

def total_price

line_items.to_a.sum { |item| item.total_price }

end

model/cart.rb

def total_price

product.price  * quantity

end

my second option is

def total_price

 if product.price

   product.price * quantity

 else

   product.price = "0.0".to_d

This code is assigning a 0 to fixed price of a product (most probably not what is intended). Probably simply return a 0 (in BigDecimal) here.

end

end

but still this wont work

Is there a business rule that each item must realistically have a quantity and product (and that product must have a price) ?

In that case I suggest:

  • add validations for the presence of these values

    (presence of quantity and product on item presence of price on product)

  • write code like:

def total_price

 if self.valid?
  product.price * quantity

 else

   0.to_d

 end

end

Another possible gotcha is that “item.product_id” is available (e.g. from a select box), but item.product is not yet associated (you may need to override the product_id= setter for that e.g.

def product_id=(product_id) self.product = Product.find_by_id(product_id) super end

HTH,

Peter

Is there a business rule that each item must realistically have a quantity and product (and that product must have a price) ?

uhm im following agile web development rails actualy the snippets are from the book

* add validations for the presence of these values (presence of quantity and product on item presence of price on product)

i already validated the price of each item in CRUD

model/product.rb   validates :price, :numericality => {:greater_than_or_equal_to => 0.01}

im trying to to follow your suggestion but nothing happens it was still the same as it was :frowning:

For clarity. It is not because a validation is present that the value is always present in memory (in the database, using the standard techniques for saving, only valid data should ever be

really saved).

Is the data for the item valid?

  • quantity
  • product
  • product_id

Check out the values of those 3.

HTH,

Peter

yes those data are valid actualy a while ago it worked but when i clear and destroy the cart it returned to this error very much appreciated for your effort thank you

app/models/line_item.rb:24:in `*' app/models/line_item.rb:24:in `total_price' app/views/carts/show.html.erb:7:in `block in _app_views_carts_show_html_erb___389431939__618846538' activerecord (3.1.1) lib/active_record/associations/collection_proxy.rb:91:in `each' activerecord (3.1.1) lib/active_record/associations/collection_proxy.rb:91:in `method_missing' app/views/carts/show.html.erb:3:in `_app_views_carts_show_html_erb___389431939__618846538' actionpack (3.1.1) lib/action_view/template.rb:144:in `block in render' activesupport (3.1.1) lib/active_support/notifications.rb:55:in `instrument' actionpack (3.1.1) lib/action_view/template.rb:142:in `render' actionpack (3.1.1) lib/action_view/renderer/template_renderer.rb:40:in `block (2 levels) in render_template' actionpack (3.1.1) lib/action_view/renderer/abstract_renderer.rb:33:in `block in instrument' activesupport (3.1.1) lib/active_support/notifications.rb:53:in `block in instrument' activesupport (3.1.1) lib/active_support/notifications/instrumenter.rb:21:in `instrument' activesupport (3.1.1) lib/active_support/notifications.rb:53:in `instrument' actionpack (3.1.1) lib/action_view/renderer/abstract_renderer.rb:33:in `instrument' actionpack (3.1.1) lib/action_view/renderer/template_renderer.rb:39:in `block in render_template' actionpack (3.1.1) lib/action_view/renderer/template_renderer.rb:47:in `render_with_layout' actionpack (3.1.1) lib/action_view/renderer/template_renderer.rb:38:in `render_template' actionpack (3.1.1) lib/action_view/renderer/template_renderer.rb:12:in `block in render' actionpack (3.1.1) lib/action_view/renderer/abstract_renderer.rb:22:in `wrap_formats' actionpack (3.1.1) lib/action_view/renderer/template_renderer.rb:9:in `render' actionpack (3.1.1) lib/action_view/renderer/renderer.rb:36:in `render_template' actionpack (3.1.1) lib/action_view/renderer/renderer.rb:17:in `render' actionpack (3.1.1) lib/abstract_controller/rendering.rb:120:in `_render_template' actionpack (3.1.1) lib/action_controller/metal/streaming.rb:250:in `_render_template' actionpack (3.1.1) lib/abstract_controller/rendering.rb:114:in `render_to_body' actionpack (3.1.1) lib/action_controller/metal/renderers.rb:30:in `render_to_body' actionpack (3.1.1) lib/action_controller/metal/compatibility.rb:43:in `render_to_body' actionpack (3.1.1) lib/abstract_controller/rendering.rb:99:in `render' actionpack (3.1.1) lib/action_controller/metal/rendering.rb:16:in `render' actionpack (3.1.1) lib/action_controller/metal/instrumentation.rb:40:in `block (2 levels) in render' activesupport (3.1.1) lib/active_support/core_ext/benchmark.rb:5:in `block in ms' /home/led/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/benchmark.rb:310:in `realtime' activesupport (3.1.1) lib/active_support/core_ext/benchmark.rb:5:in `ms' actionpack (3.1.1) lib/action_controller/metal/instrumentation.rb:40:in `block in render' actionpack (3.1.1) lib/action_controller/metal/instrumentation.rb:78:in `cleanup_view_runtime' activerecord (3.1.1) lib/active_record/railties/controller_runtime.rb:24:in `cleanup_view_runtime' actionpack (3.1.1) lib/action_controller/metal/instrumentation.rb:39:in `render' actionpack (3.1.1) lib/action_controller/metal/implicit_render.rb:10:in `default_render' actionpack (3.1.1) lib/action_controller/metal/mime_responds.rb:268:in `block in retrieve_response_from_mimes' actionpack (3.1.1) lib/action_controller/metal/mime_responds.rb:195:in `call' actionpack (3.1.1) lib/action_controller/metal/mime_responds.rb:195:in `respond_to' app/controllers/carts_controller.rb:22:in `show' actionpack (3.1.1) lib/action_controller/metal/implicit_render.rb:4:in `send_action' actionpack (3.1.1) lib/abstract_controller/base.rb:167:in `process_action' actionpack (3.1.1) lib/action_controller/metal/rendering.rb:10:in `process_action' actionpack (3.1.1) lib/abstract_controller/callbacks.rb:18:in `block in process_action' activesupport (3.1.1) lib/active_support/callbacks.rb:416:in `_run__371692982__process_action__266900328__callbacks' activesupport (3.1.1) lib/active_support/callbacks.rb:386:in `_run_process_action_callbacks' activesupport (3.1.1) lib/active_support/callbacks.rb:81:in `run_callbacks' actionpack (3.1.1) lib/abstract_controller/callbacks.rb:17:in `process_action' actionpack (3.1.1) lib/action_controller/metal/rescue.rb:17:in `process_action' actionpack (3.1.1) lib/action_controller/metal/instrumentation.rb:30:in `block in process_action' activesupport (3.1.1) lib/active_support/notifications.rb:53:in `block in instrument' activesupport (3.1.1) lib/active_support/notifications/instrumenter.rb:21:in `instrument' activesupport (3.1.1) lib/active_support/notifications.rb:53:in `instrument' actionpack (3.1.1) lib/action_controller/metal/instrumentation.rb:29:in `process_action' actionpack (3.1.1) lib/action_controller/metal/params_wrapper.rb:201:in `process_action' activerecord (3.1.1) lib/active_record/railties/controller_runtime.rb:18:in `process_action' actionpack (3.1.1) lib/abstract_controller/base.rb:121:in `process' actionpack (3.1.1) lib/abstract_controller/rendering.rb:45:in `process' actionpack (3.1.1) lib/action_controller/metal.rb:193:in `dispatch' actionpack (3.1.1) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch' actionpack (3.1.1) lib/action_controller/metal.rb:236:in `block in action' actionpack (3.1.1) lib/action_dispatch/routing/route_set.rb:65:in `call' actionpack (3.1.1) lib/action_dispatch/routing/route_set.rb:65:in `dispatch' actionpack (3.1.1) lib/action_dispatch/routing/route_set.rb:29:in `call' rack-mount (0.8.3) lib/rack/mount/route_set.rb:152:in `block in call' rack-mount (0.8.3) lib/rack/mount/code_generation.rb:96:in `block in recognize' rack-mount (0.8.3) lib/rack/mount/code_generation.rb:96:in `optimized_each' rack-mount (0.8.3) lib/rack/mount/code_generation.rb:95:in `recognize' rack-mount (0.8.3) lib/rack/mount/route_set.rb:141:in `call' actionpack (3.1.1) lib/action_dispatch/routing/route_set.rb:532:in `call' actionpack (3.1.1) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call' rack (1.3.6) lib/rack/etag.rb:23:in `call' rack (1.3.6) lib/rack/conditionalget.rb:25:in `call' actionpack (3.1.1) lib/action_dispatch/middleware/head.rb:14:in `call' actionpack (3.1.1) lib/action_dispatch/middleware/params_parser.rb:21:in `call' actionpack (3.1.1) lib/action_dispatch/middleware/flash.rb:243:in `call' rack (1.3.6) lib/rack/session/abstract/id.rb:195:in `context' rack (1.3.6) lib/rack/session/abstract/id.rb:190:in `call' actionpack (3.1.1) lib/action_dispatch/middleware/cookies.rb:331:in `call' activerecord (3.1.1) lib/active_record/query_cache.rb:62:in `call' activerecord (3.1.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:477:in `call' actionpack (3.1.1) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call' activesupport (3.1.1) lib/active_support/callbacks.rb:392:in `_run_call_callbacks' activesupport (3.1.1) lib/active_support/callbacks.rb:81:in `run_callbacks' actionpack (3.1.1) lib/action_dispatch/middleware/callbacks.rb:28:in `call' actionpack (3.1.1) lib/action_dispatch/middleware/reloader.rb:68:in `call' rack (1.3.6) lib/rack/sendfile.rb:101:in `call' actionpack (3.1.1) lib/action_dispatch/middleware/remote_ip.rb:48:in `call' actionpack (3.1.1) lib/action_dispatch/middleware/show_exceptions.rb:47:in `call' railties (3.1.1) lib/rails/rack/logger.rb:13:in `call' rack (1.3.6) lib/rack/methodoverride.rb:24:in `call' rack (1.3.6) lib/rack/runtime.rb:17:in `call' activesupport (3.1.1) lib/active_support/cache/strategy/local_cache.rb:72:in `call' rack (1.3.6) lib/rack/lock.rb:15:in `call' actionpack (3.1.1) lib/action_dispatch/middleware/static.rb:53:in `call' railties (3.1.1) lib/rails/engine.rb:456:in `call' railties (3.1.1) lib/rails/rack/content_length.rb:16:in `call' railties (3.1.1) lib/rails/rack/log_tailer.rb:14:in `call' rack (1.3.6) lib/rack/handler/webrick.rb:59:in `service' /home/led/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service' /home/led/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run' /home/led/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'

its the full trace of the error cant seems to find it im a week old in ruby on rails development

hi guys im playing with RoR with the environment of rails 3 ruby 1.9 i got stuck in

nil can't be coerced into BigDecimal

  def total_price    line_items.to_a.sum { |item| item.total_price } end model/cart.rb

That error would be expected when some of line_items.total_price returns nil. Moreover you can sum total prices without .to_a, that would be more efficient.

def total_price    product.price * quantity end

def total_price     if product.price       product.price * quantity     else       product.price = "0.0".to_d

  It is not necessary to write attribute :price, just let it return zero. 0.to_d in this case.   

    end   end

Now. before test it again, check in the database if any product has a nil or any non-bigdecimal value.

nil can't be coerced into BigDecimal

  def total_price    line_items.to_a.sum { |item| item.total_price } end model/cart.rb

That error would be expected when some of line_items.total_price returns nil. Moreover you can sum total prices without .to_a, that would be more efficient.

tried to applying this but gotting the problem in the view

def total_price    product.price * quantity end

def total_price     if product.price       product.price * quantity     else       product.price = "0.0".to_d

  It is not necessary to write attribute :price, just let it return zero. 0.to_d in this case.

i tried this and it worked out but when reseting the cart it return the error

    end   end

Now. before test it again, check in the database if any product has a nil or any non-bigdecimal value.

this is being weird when i tried your suggestion it worked out but when i clear delete the cart again it return to the error :frowning:

i tried refactoring my destroy method now its working fine but my second issue is when i add item to the cart at first attemp it returns to that error again but returning to the product list it worked fine im just wondering if my add_product is code is ok?

def add_product(product_id)     current_item = line_items.where(:product_id => product_id).first

     if current_item         current_item.quantity = current_item.quantity.to_i + 1       else         current_item = LineItem.new(:product_id=>product_id)         line_items << current_item       end         current_item    end

I didn't see you code completely, but

line_items.to_a.sum { |item| item.total_price }

How can it count correct if only ONE item in the cart? :slight_smile:

Obviously, if you want to get Array, use Array.wrap method like this:

Array.wrap(line_items).sum { |item| item.total_price }

Valery Kvon wrote in post #1047975:

I didn't see you code completely, but

line_items.to_a.sum { |item| item.total_price }

How can it count correct if only ONE item in the cart? :slight_smile:

Obviously, if you want to get Array, use Array.wrap method like this:

Array.wrap(line_items).sum { |item| item.total_price }

i tried Array.wrap(line_items).sum { |item| item.total_price } also it worked same as the line_items.to_a.sum { |item| item.total_price } (i think?) but im having the issue of not counting my first attemp maybe my add_product code is wrong?

def add_product(product_id)     current_item = line_items.where(:product_id => product_id).first

     if current_item         current_item.quantity = current_item.quantity.to_i + 1       else         current_item = LineItem.new(:product_id=>product_id)         line_items << current_item       end         current_item    end

it feels like im adding a nil value at my first attemp of adding a product into my cart? btw thanks for your concern with my post :slight_smile:

It is not the item that is nil but total_price. If it were the item that were nil then you would get an error saying that nil did not have a method total_price. Where are you setting total_price when you do LineItem.new.

Colin

def add_product(product_id)    current_item = line_items.where(:product_id => product_id).first

    if current_item        current_item.quantity = current_item.quantity.to_i + 1      else        current_item = LineItem.new(:product_id=>product_id)        line_items << current_item

  Ok, let's imagine. You add new LineItem and product.price is nil or quantity is nil   then   product.price * quantity   would raise error "nil can't be coerced into…"

  Check if product price or quantity is nil after initialize LineItem.new

Colin Law wrote in post #1047978:

it feels like im adding a nil value at my first attemp of adding a product into my cart?

It is not the item that is nil but total_price. If it were the item that were nil then you would get an error saying that nil did not have a method total_price. Where are you setting total_price when you do LineItem.new.

i belive im setting it in the current_item it self current_item = LineItem.new(:product_id=>product_id)

Show us the code of LineItem class.

This method raises the error on a new instance. To avoid it, it must return BigDec anytime. In your case product.price is nil or quantity is nil..

def total_price    product.price * quantity end

As I wrote above. This sets the product_id, but not necessarily the “product” association. Check values of

  • current_item.product_id
  • current_item.product right after this line.

HTH,

Peter

Valery Kvon wrote in post #1047982:

Show us the code of LineItem class.

This method raises the error on a new instance. To avoid it, it must return BigDec anytime. In your case product.price is nil or quantity is nil..

def total_price    product.price * quantity end

class LineItem < ActiveRecord::Base   belongs_to :product   belongs_to :cart

  def total_price      if product.price        product.price = product.price * quantity      else         0.to_d      end    end end

this is my model/line item.rb

So.

I agree that: 1) current_item = LineItem.new(:product_id=>product_id) = BAD IDEA. Because, if you pass the invalid product ID, LineItem would be initialized as well, but the .product association would return nil.

2) Actually I didn't see how quantity is set up? Looking at your previous code it must be method 'quantity'.

PS. Why are you writing product.price=?

Valery Kvon wrote in post #1047990:

  end end

So.

I agree that: 1) current_item = LineItem.new(:product_id=>product_id) = BAD IDEA. Because, if you pass the invalid product ID, LineItem would be initialized as well, but the .product association would return nil.

do you think current_item = line_items.build(:product_id => product_id) is better?

2) Actually I didn't see how quantity is set up? Looking at your previous code it must be method 'quantity'.

i dont have a method quantity

PS. Why are you writing product.price=?

i belive it is same with product.price * quantity to show the sum of all products inside my cart

Valery Kvon wrote in post #1047990:

I agree that: 1) current_item = LineItem.new(:product_id=>product_id) = BAD IDEA. Because, if you pass the invalid product ID, LineItem would be initialized as well, but the .product association would return nil.

do you think current_item = line_items.build(:product_id => product_id) is better?

no, the correct way is:

product = Product.find(product_id) # it will raise AcriveRecord::RecordNotFound if invalid product_id passed. current_item = LineItem.new(:product => product) # or current_item = LineItem.new; current_item.product = product

2) Actually I didn't see how quantity is set up? Looking at your previous code it must be method 'quantity'.

i dont have a method quantity

In this case it does not work ever. def total_count - is an instance method. If you use 'quantity', so it just MUST be an another instance method or local variable. There is something wrong with app's logic.

PS. Why are you writing product.price=?

i belive it is same with product.price * quantity to show the sum of all products inside my cart

Logic, logic, logic….

product - is a stand alone instance or One product. Why Would it ever have the multiplied price with 'quantity' ?.

I remember many years ago I read the beginner's book "Agile Web Development with Rails", is that example from it? I think you missed something.