Ruby on Rails中的虚拟属性

时间:2013-01-24 13:02:07

标签: ruby-on-rails ruby rails-activerecord

我是Rails的新手。我不明白我在这里做错了什么。

我有以下型号order.rb,虚拟属性值为:

    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

此模型在rails控制台中运行良好,我可以在其中设置值并计算数量。

问题是当我尝试可视化表单时。 app / views / orders / new.html.erb呈现以下_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 %>

我在浏览器中打开页面时遇到错误,在_form.html.erb的行中引发了文本字段值:

Orders#new中的NoMethodError nil的未定义方法`*':NilClass

我做错了什么?我试图关注http://railscasts.com/episodes/16-virtual-attributes

1 个答案:

答案 0 :(得分:3)

对于新建的订单对象,价格为零。所以你得到了这个错误。

在计算价值之前,请确保您有价格和数量

  def value
    return unless price || quantity
    price * quantity
  end