Ruby on Rails nil不能强制转换为BigDecimal [英] Ruby on Rails nil can't be coerced into BigDecimal

查看:95
本文介绍了Ruby on Rails nil不能强制转换为BigDecimal的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我尝试执行计算时会得到nil can't be coerced into BigDecimal:这是代码:

Why do I get nil can't be coerced into BigDecimal when I try to perform a calculation: here's the code:

model/drink.rb

class Drink < ActiveRecord::Base
  belongs_to :menu 
  before_save :total_amount 

def total_amount
    self.total_amount = self.price * self.quantity
end 

model/menu.rb

class Menu < ActiveRecord::Base
    has_many :drinks, :dependent => :destroy
    accepts_nested_attributes_for :drinks, :allow_destroy => true
    #Validations

end

* 饮料是(嵌套的)子模型,菜单是父模型.当我尝试创建新饮料时,浏览器会显示以下错误消息nil can't be coerced into BigDecimal app/models/drink.rb:7:in 'total-amount' app/controllers/menus_controller.rb:47:in 'create' app/controllers/menus_controller.rb:46:in 'create'

*Drink is the (nested)child model and Menu the parent model When I attempt to create a new drink the browser display following error message nil can't be coerced into BigDecimal app/models/drink.rb:7:in 'total-amount' app/controllers/menus_controller.rb:47:in 'create' app/controllers/menus_controller.rb:46:in 'create'

app/db/migration

app/db/migration

class CreateDrinks < ActiveRecord::Migration
  def change
    create_table :drinks do |t|
      t.string :name
      t.decimal :quantity,:precision => 8, :scale => 2
      t.decimal :price, :precision => 8, :scale => 2
      t.decimal :vat, :precision => 8, :scale => 2
      t.references :menu

      t.timestamps
    end
    add_index :drinks, :menu_id
  end
end

controllers/drinks_controller.rb

   class DrinksController < ApplicationController
      # GET /drinks
      # GET /drinks.json
      def index
        @drinks = Drink.all

        respond_to do |format|
          format.html # index.html.erb
          format.json { render :json => @drinks }
        end
      end

      # GET /drinks/1
      # GET /drinks/1.json
      def show
        @drink = Drink.find(params[:id])

        respond_to do |format|
          format.html # show.html.erb
          format.json { render :json => @drink }
        end
      end

      # GET /drinks/new
      # GET /drinks/new.json
      def new
        @drink = Drink.new

        respond_to do |format|
          format.html # new.html.erb
          format.json { render :json => @drink }
        end
      end

      # GET /drinks/1/edit
      def edit
        @drink = Drink.find(params[:id])
      end

      # POST /drinks
      # POST /drinks.json
      def create
        @article = Drink.new(params[:drink])

        respond_to do |format|
          if @drink.save
            format.html { redirect_to @drink, :notice => 'Drink was successfully created.' }
            format.json { render :json => @drink, :status => :created, :location => @article }
          else
            format.html { render :action => "new" }
            format.json { render :json => @drink.errors, :status => :unprocessable_entity }
          end
        end
      end

      # PUT /drinks/1
      # PUT /drinks/1.json
      def update
        @drink = Drink.find(params[:id])

        respond_to do |format|
          if @drink.update_attributes(params[:drink])
            format.html { redirect_to @drink, :notice => 'Drink was successfully updated.' }
            format.json { head :ok }
          else
            format.html { render :action => "edit" }
            format.json { render :json => @drink.errors, :status => :unprocessable_entity }
          end
        end
      end

      # DELETE /drinks/1
      # DELETE /drinks/1.json
      def destroy
        @drink = Drink.find(params[:id])
        @drink.destroy

        respond_to do |format|
          format.html { redirect_to drinks_url }
          format.json { head :ok }
        end
      end 
    end 

请任何人告诉我代码有什么问题吗?

Please can anyone tell me what's wrong with the code?

推荐答案

如果您希望nil的值为0.0,则可以执行以下操作:

If you want nil to be evaluated as 0.0 then you can do something like this:

def total_amount
    self.total_amount = self.price.to_s.to_d * self.quantity.to_s.to_d
end 

或显式检查是否为零

def total_amount
  if self.price && self.quantity
    self.total_amount = self.price * self.quantity
  else
    self.total_amount = "0.0".to_d
  end
end 

问题实际上是您的记录字段设置得不像您期望的那样.您是否需要使用验证来确保设置了pricequantity字段?

The problem is really that your record fields aren't set like you expect them to be. Do you need to use validations to make sure that the price and quantity fields are set?

class Drink
  validates :price, :presence => true      # Don't forget add DB validations, too :)
  validates :quantity, :presence => true
end

这样,您可以确保在调用#total_amount时不会得到nil值.

That way you ensure that you don't get a nil value when calling #total_amount.

这篇关于Ruby on Rails nil不能强制转换为BigDecimal的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆