Reputation: 53
I am a newbie in Rails. I am not understanding what I'm doing wrong here.
I have the following model order.rb, with a virtual attribute value:
class Order < ActiveRecord::Base
ACTIONS = %w(buy sell)
ORDER_TYPES = %w(LMT STP)
TIFS = %w(DAY GTC OPG IOC)
attr_accessible :action, :price, :quantity, :symbol, :tif, :order_type, :value
validates :action, :symbol, :tif, :order_type, presence: true
validates :price, numericality: { greater_than_or_equal_to: 0.0001 }
validates :quantity, numericality: { only_integer: true, greater_than: 0 }
validates :action, inclusion: ACTIONS
validates :order_type, inclusion: ORDER_TYPES
validates :tif, inclusion: TIFS
def value
price * quantity
end
def value= (val)
self.quantity = val / self.price
end
end
This model works fine in rails console, where I can set value and it calculates quantity.
The problem is when I try to visualize the form. app/views/orders/new.html.erb renders the following _form.html.erb:
<%= form_for @order, html: { :class => 'form-inline' } do |f| %>
<% if @order.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@order.errors.count, "error") %> prohibited this order from being saved:</h2>
<ul>
<% @order.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<fieldset>
<legend><%= params[:action].capitalize %> Order</legend>
<table class="table">
<thead>
<tr>
<th><%= f.label :action %></th>
<th><%= f.label :symbol %></th>
<th><%= f.label :price %></th>
<th><%= f.label :value %></th>
<th><%= f.label :order_type %></th>
<th><%= f.label :tif, "TIF" %></th>
</tr>
</thead>
<tbody>
<tr>
<td><%= f.select :action, Order::ACTIONS, {}, class: 'input-small' %></td>
<td><%= f.text_field :symbol, class: 'input-small' %></td>
<td><%= f.text_field :price, class: 'input-small' %></td>
<td><%= f.text_field :value, class: 'input-small' %></td>
<td><%= f.select :order_type, Order::ORDER_TYPES, {}, class: 'input-small' %></td>
<td><%= f.select :tif, Order::TIFS, {}, class: 'input-small' %></td>
</tr>
</tbody>
</table>
<%= f.submit "Submit", class: "btn btn-primary" %>
<%= f.submit "Clear", class: "btn", type: "reset" %>
</fieldset>
<% end %>
I get an error when I open the page in the browser, raised on the line of _form.html.erb with the text field value:
NoMethodError in Orders#new undefined method `*' for nil:NilClass
What am I doing wrong? I tried to follow http://railscasts.com/episodes/16-virtual-attributes
Upvotes: 0
Views: 670
Reputation: 6728
For the newly built order object price is nil. So you are getting this error.
Before calculating value make sure that you have price and quantity
def value
return unless price || quantity
price * quantity
end
Upvotes: 3