Ruby on Rails nil无法强制转换为BigDecimal

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

模型/ drink.rb

 class Drink < ActiveRecord::Base belongs_to :menu before_save :total_amount def total_amount self.total_amount = self.price * self.quantity end 

模型/ menu.rb

 class Menu  :destroy accepts_nested_attributes_for :drinks, :allow_destroy => true #Validations end 

* Drink是(嵌套)子模型,Menu是父模型当我尝试创建新饮料时,浏览器显示以下错误消息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'

应用程序/分贝/迁移

 class CreateDrinks  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 

控制器/ drinks_controller.rb

  class DrinksController  @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 

请问有谁可以告诉我代码有什么问题?

如果你想将nil评估为0.0,那么你可以这样做:

 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 

问题实际上是你的记录字段没有像你期望的那样设置。 您是否需要使用validation来确保设置pricequantity字段?

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

这样你就可以确保在调用#total_amount时没有得到nil值。

您没有在任何地方设置quantity值,因此它nil并且无法将nil强制转换为乘法数。

据推测,您的price是数据库中的decimal(n,2) (对于某些n ),因此self.price在Ruby中表示为BigDecimal对象; 这就是为什么你得到关于不能强迫BigDecimal的投诉。

你可以从这样的irb得到类似的错误:

 >> 11 * nil TypeError: nil can't be coerced into Fixnum from (irb):7:in `*' 

你的self.price已设置好了。 如果不是那么你会得到其中一个:

 NoMethodError: undefined method `*' for nil:NilClass 

您可能想要添加

 validates_presence_of :quantity, :price 

(或者可能更严格的validation),如果您要求设置它们。