Reputation: 1596
I have a really simple cost model which belongs to an order.
Each cost has a value and quantity and I'm calculating the total using:
def set_total
@set_total = quantity * amount
end
This works great and in my costs views, I can call with:
<td><%= number_to_currency(cost.set_total, :unit => "£") %></td>
However, I don't seem to be able to show this in my orders show view - get a NoMethodError:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.*
In orders, show, I have this:
<% unless @order.costs.empty? %>
<% @order.costs.each do |cost| %>
<%= cost.description %>
<%= cost.cost_type %>
<%= number_to_currency(cost.amount, :unit => "£") %>
<%= cost.quantity %>
<%= cost.set_total %>
<% end %>
<% end %>
My routes are setup fine:
resources :orders do
:costs
end
If I use a table to display the information, I get a blank line at the end. Costs partial:
<% unless @order.costs.empty? %>
<table border='1' cellpadding="5">
<tr>
<th>Description</th>
<th>Type</th>
<th>Amount</th>
<th>Quantity</th>
<th>Total</th>
</tr>
<% @order.costs.each do |cost| %>
<tr>
<td><%= cost.description %></td>
<td><%= cost.cost_type %></td>
<td><%= number_to_currency(cost.amount, :unit => "£") %></td>
<td><%= cost.quantity %></td>
<td><%= cost.set_total %></td>
</tr>
<% end %>
</table>
<% end %>
Can see an extra table row at the bottom and can't see why. Think this is leading to the nil value.
--edit--
With debugging on, I can still see extra lines:
!ruby/ActiveRecord:Cost
attributes:
description:
cost_type:
amount:
order_id: 14
code:
created_at:
updated_at:
quantity:
Which doesn't make sense because I've just reset the db... Why is a blank cost created, with no ID even.
UPDATE
class CostsController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource
def index
@costs = Cost.paginate(:per_page => 3, :page => params[:page])
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @costs }
end
end
def show
@costs = Cost.find(params[:id])
end
def new
end
def edit
end
def create
@order = Order.find(params[:order_id])
@cost = @order.costs.create(params[:cost])
redirect_to order_path(@order)
end
end
Upvotes: 0
Views: 331
Reputation: 4930
Could you please post your controller code ?
I would think that you build a new cost in your controller, using something like @orders.costs.new
or @orders.costs.build
?
Your last comment about the table showing even if there are no cost for this order validate this hypothesis
UPDATE:
Also for the method set_total, you should consider to refactor it to :
def total
@total ||= quantity.to_i * amount
end
Using this code the total value will be cached for other called to total
on this object.
Using total instead of set_total for the name of the method is more close to the ruby/rails convention.
Upvotes: 1
Reputation: 7803
There is something up with your costs.
when you create then are you using @order.costs.new(....)
make sure you save them after that, that could be the problem.
Try using the console to create and play with an object, see if it is failing validation, not saving etc
Upvotes: 0
Reputation: 6021
The error occurred while evaluating nil.*
that error mean that you trying to call *
method on the nil
object.
def set_total
@set_total = quantity * amount
end
Make sure that quantity
attribute is set to not nil value for each Cost
record.
or change your method to:
def set_total
@set_total = (quantity || 0) * amount
end
Upvotes: 1