0
votes

I am NEW ON learning Ruby on Rails. I am following the book Agile Web Development with Rails 4. I nearly have finished Chapter 10: Smarter Card. I have to create a Method for LineItem and Cart models that returns the total price for the individual item and entire card. When I start my server, I get the error notification "nil can't be coerced into BigDecimal".

What was weird: It worked.

    Started GET "/carts/38" for 127.0.0.1 at 2014-10-24 22:16:41 +0200
    Processing by CartsController#show as HTML
    Parameters: {"id"=>"38"}
    Cart Load (0.1ms)  SELECT  "carts".* FROM "carts"  WHERE "carts"."id" = ? LIMIT 1      [["id", 38]]
   LineItem Load (0.1ms)  SELECT "line_items".* FROM "line_items"  WHERE  "line_items"."cart_id" = ?  [["cart_id", 38]]
    Product Load (0.1ms)  SELECT  "products".* FROM "products"  WHERE "products"."id" = ? LIMIT 1  [["id", 4]]
    Rendered carts/show.html.erb within layouts/application (4.3ms)
    Completed 200 OK in 51ms (Views: 49.2ms | ActiveRecord: 0.3ms)


    Started GET "/assets/turbolinks.js?body=1" for 127.0.0.1 at 2014-10-24 22:16:41 +0200


    Started GET "/assets/application.css?body=1" for 127.0.0.1 at 2014-10-24 22:16:41  +0200


    Started GET "/assets/carts.js?body=1" for 127.0.0.1 at 2014-10-24 22:16:41 +0200


    Started GET "/assets/jquery.js?body=1" for 127.0.0.1 at 2014-10-24 22:16:41 +0200


    Started GET "/assets/jquery_ujs.js?body=1" for 127.0.0.1 at 2014-10-24 22:16:41 +0200


   Started GET "/assets/line_items.js?body=1" for 127.0.0.1 at 2014-10-24 22:16:41 +0200


  Started GET "/assets/store.js?body=1" for 127.0.0.1 at 2014-10-24 22:16:41 +0200


  Started GET "/assets/products.js?body=1" for 127.0.0.1 at 2014-10-24 22:16:41 +0200


  Started GET "/assets/application.js?body=1" for 127.0.0.1 at 2014-10-24 22:16:41 +0200


  Started GET "/assets/logo.png" for 127.0.0.1 at 2014-10-24 22:16:41 +0200


  Started DELETE "/carts/38" for 127.0.0.1 at 2014-10-24 22:19:11 +0200
  Processing by CartsController#destroy as HTML
  Parameters: {"authenticity_token"=>"EhOlirn9iTrL0fXoxCLWWKQSsSPN4lNWoF0Rv2M873M=",  "id"=>"38"}
  Cart Load (0.1ms)  SELECT  "carts".* FROM "carts"  WHERE "carts"."id" = ? LIMIT 1   [["id", 38]]
 (0.1ms)  begin transaction
  LineItem Load (0.1ms)  SELECT "line_items".* FROM "line_items"  WHERE  "line_items"."cart_id" = ?  [["cart_id", 38]]
 SQL (0.3ms)  DELETE FROM "line_items" WHERE "line_items"."id" = ?  [["id", 35]]
 SQL (0.1ms)  DELETE FROM "carts" WHERE "carts"."id" = ?  [["id", 38]]
 (0.6ms)  commit transaction
 Redirected to http://0.0.0.0:3000/
 Completed 302 Found in 4ms (ActiveRecord: 1.2ms)

After I pressed the button "Empty Cart" and pressed the refresh button I got the error.

 Started GET "/carts/36" for 127.0.0.1 at 2014-10-24 23:18:29 +0200
 ActiveRecord::SchemaMigration Load (0.4ms)  SELECT "schema_migrations".* FROM        "schema_migrations"
 Processing by CartsController#show as HTML
 Parameters: {"id"=>"36"}
 Cart Load (0.2ms)  SELECT  "carts".* FROM "carts"  WHERE "carts"."id" = ? LIMIT 1       [["id", 39]]
  LineItem Load (0.7ms)  SELECT "line_items".* FROM "line_items"  WHERE    "line_items"."cart_id" = ?  [["cart_id", 39]]
  Product Load (0.2ms)  SELECT  "products".* FROM "products"  WHERE "products"."id" = ?  LIMIT 1  [["id", 4]]
  Rendered carts/show.html.erb within layouts/application (67.2ms)
 Completed 500 Internal Server Error in 96ms

 ActionView::Template::Error (nil can't be coerced into BigDecimal):
    9:     <tr>
   10:       <td><%= item.quantity %>&times;</td>
   11:       <td><%= item.product.title %></td>
   12:       <td class="item_price"><%= number_to_currency(item.total_price) %></td>
   13:    </tr>
   14: <% end %>
   15: 
 app/models/line_item.rb:9:in `*'
 app/models/line_item.rb:9:in `total_price'
 app/views/carts/show.html.erb:12:in `block in   _   app_views_carts_show_html_erb___3008945911568791515_70186161526860'
 app/views/carts/show.html.erb:8:in `    _app_views_carts_show_html_erb___3008945911568791515_70186161526860'


 Rendered /Users/eichmann/.rvm/gems/ruby-2.1.2/gems/actionpack-  4.1.4/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.4ms)
 Rendered /Users/eichmann/.rvm/gems/ruby-2.1.2/gems/actionpack-4.1.4/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (0.9ms)
 Rendered /Users/eichmann/.rvm/gems/ruby-2.1.2/gems/actionpack-4.1.4/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within    rescues/layout (12.8ms)

Model of the Cart

class Cart < ActiveRecord::Base
  has_many :line_items, dependent: :destroy



  def add_product(product_id)
    current_item = line_items.find_by(product_id: product_id)
    if current_item
     current_item.quantity = current_item.quantity.to_i + 1
    else
     current_item = line_items.build(product_id: product_id)
   end
   current_item
  end

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

Model of LineItem

  class LineItem < ActiveRecord::Base
  belongs_to :product
  belongs_to :cart
  validates :product_id, presence: true
  validates :cart_id, presence: true


  def total_price
  product.price * quantity
  end
  end

View Carts #Show

<% if notice %>
<%= notice %>
<p id="notice"><%= notice %></p>
<% end %>

<h2>Your Cart </h2>
<table>
  <% @cart.line_items.each do |item| %>
    <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>


<%= link_to 'Empty cart', @cart, method: :delete, data: { confirm: 'Are you sure?' } %>

def destroy @line_item.destroy respond_to do |format| format.html { redirect_to line_items_url, notice: 'Line item was successfully destroyed.' } format.json { head :no_content } end end

 private
   # Use callbacks to share common setup or constraints between actions.
   def set_line_item
     @line_item = LineItem.find(params[:product_id])
   end
 end

# Never trust parameters from the scary internet, only allow the white list through.
def line_item_params
  params.require(:line_item).permit(:product_id)
end

Controller Card

def create
    @cart = Cart.new(cart_params)

    respond_to do |format|
      if @cart.save
        format.html { redirect_to @cart, notice: 'Cart was successfully created.' }
        format.json { render :show, status: :created, location: @cart }
      else
        format.html { render :new }
        format.json { render json: @cart.errors, status: :unprocessable_entity }
      end
    end
  end

Cart Controller destroy

def destroy
   @cart.destroy if @cart.id == session[:cart_id]
   session[:cart_id] = nil

   respond_to do |format|
     format.html { redirect_to store_url, notice: 'Your cart is currently empty.' }
     format.json { head :no_content }
   end
 end

My db

 class AddQuantityToLineItems < ActiveRecord::Migration
   def change
     add_column :line_items, :quantity, :integer, default: 0
   end
 end
1
Please add stacktrace to your question.Esse
Of course, here we goKeeic
Can you please also paste code for carts_controller#destroy?Esse
Again, here we go with the #destroyKeeic
I think you find the cart in CartsController with session[:cart_id] instead of params[:id]. Am I right?Alejandro Babio

1 Answers

0
votes

Quantitity of one of your line items is nil. In total_price you're trying to multiply price by nil which results in error.

I would recommend adding default value to column in database - quantity of line_item should default to 0.