Home > Enterprise >  NoMethodError in Orders#show , undefined method `grand_total' for nil:NilClass
NoMethodError in Orders#show , undefined method `grand_total' for nil:NilClass

Time:10-06

I'm want to show the grand_total to the show page and i have do a partial file to put in the table, in inside i want to grab the orderproduct data and show to front , but it show me this error. It seem like i didn't define method grand_total, but not sure how to solve it.

Orders controller

class OrdersController < ApplicationController

 def supplier
  @supplier = Supplier.find(params[:id])
 end

 def outlet
  @outlet = Outlet.find(params[:id])
 end

 def index
  @orders = Order.all
 end

 def show
  @orders = Order.all
  @order_products = OrderProduct.all
 end

def new
 @order = Order.new
 @supplier = Supplier.all
 @outlet = Outlet.all
 @products = Product.all
end

def create
 @order = Order.new(order_params)
 @supplier_id = Supplier.all
 @outlet_id = Outlet.all
 if @order.save
  product_ids = params[:product_ids]
  product_ids.each do |product_id|
    OrderProduct.create(order_id: @order.id, product_id: product_id)
  end
   flash[:success] = "Succesful create!"
   redirect_to @order
 else
   render 'new'
 end
end

private

def order_params
  params.require(:order).permit(:supplier_id,:quantity, :grand_total, :order_date,
                                :delivery_date, :delivery_address, :outlet_id)
 end
end

_orderproduct.html.erb

<div >
 <ul >
  <li >
   <div >Product</div>
   <div >Price</div>
   <div >Grand_total</div>
  </li>
  <% @order_products.each do |order_product| %>
  <li >
   <div  data-label="Product"><%= order_product.product.name %></div>
   <div  data-label="Price"><%= order_product.product.price %></div>
   <div  data-label="Grand_total"><%= order_product.order.grand_total %></div>
  <% end %>
 </ul>
</div>

show.html.erb

<% provide(:title)%>

<h2 >Order details</h2>

<div >
 <aside >
  <section >
   <%= render 'shared/stats' %>
  </section>
  <%= render 'orders/orderproduct' %>
  <div >
   <button ><%= link_to "Back to home", home_path %></button>
  </div>
 </aside>
</div>

Error show in website

CodePudding user response:

The only place in your examples on which you call grant_total is this:

<%= order_product.order.grand_total %>

The error message tells that there is a NoMethodError in Orders#show, undefined method grand_total for nil:NilClass. This means you are calling grant_total on something that is nil and not the type of object you expect. This can only happen when order_product.order returned nil. And that means you have an order_product in your database that doesn't have an order assigned.

There are several ways to fix that, depending on what you want to achieve:

  • add a validation that ensures that all order_products have an order assigned.
  • backfill missing orders in the database
  • exclude order products without associated order when loading or
  • checking if there is an order and only then outputting its grant total

CodePudding user response:

you can use debugger to see which variable is returning nil value. Check and work from there.

  • Related