2011-10-15 17 views
5

मजबूर नहीं किया जा सकता क्यों मैं nil can't be coerced into BigDecimal मिल जब मैं एक गणना करने की कोशिश करते हैं:रूबी ऑन रेल्स शून्य 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 < 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'

एप्लिकेशन/db/माइग्रेशन

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 

नियंत्रकों/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 

कृपया कर सकते हैं कोई मुझे बताता है कि कोड के साथ क्या गलत है?

+0

'price_ और' मात्रा 'के लिए 'total_amount' में आपको क्या मूल्य मिलते हैं? एक 'Logger.debug "# {self.price} # {स्वयं करें।मात्रा} '' 'कुल_माउंट' में पहली पंक्ति के रूप में। –

+0

यहां मैं लॉगर के लिए कुल_माउंट विधि 'अपरिभाषित विधि' डीबग 'में पहली पंक्ति के रूप में' Logger.debug ... 'के साथ मिलता हूं: कक्षा – blawzoo

उत्तर

15

आप तो आप कुछ इस तरह कर सकते हैं 0.0 के रूप में मूल्यांकन किया जाना नहीं के बराबर चाहते हैं टी सेट की तरह आप उन्हें होने की उम्मीद है। क्या आपको यह सुनिश्चित करने के लिए सत्यापन का उपयोग करने की आवश्यकता है कि price और quantity फ़ील्ड सेट हैं?

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

इस तरह आप सुनिश्चित करते हैं कि #total_amount पर कॉल करते समय आपको शून्य मूल्य नहीं मिलता है।

+0

धन्यवाद ओजीज़ का बहुत जादूगर आपका उत्तर पूरी तरह से काम करता है – blawzoo

+0

आपका समाधान मुझे दृश्यों में कुल_माउंट विधि को भी आमंत्रित करने में मदद करता है। आप निम्न लिंक पर समस्या देख सकते हैं: http://stackoverflow.com/questions/7774638/ruby-on-rails-calculation – blawzoo

2

आप कहीं भी quantity मूल्य सेट नहीं कर रहे हैं, इसलिए यह nil और nil गुणा के लिए एक संख्या में शामिल नहीं किया जा सकता है।

मुमकिन अपने price एक decimal(n,2) है (के लिए कुछ n) डेटाबेस इसलिए self.price एक 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 

(या संभव सख्त सत्यापन) जोड़ने के लिए अगर आप की आवश्यकता होती है कर रहे हैं कि वे हो चाहते हो सकता है सेट। के लिए नहीं के बराबर

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 

समस्या वास्तव में है कि अपने रिकॉर्ड क्षेत्रों नहीं कर रहे 'जाँच

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

या स्पष्ट रूप से:

+0

क्षमा करें आदमी लेकिन मुझे बिंदु नहीं मिला? क्या यह माइग्रेशन समस्या है? मैं एक नौसिखिया हूं इसलिए कृपया विशिष्ट रहें क्योंकि कुछ चीजें मेरे लिए बहुत सार लग सकती हैं। – blawzoo

+0

@blawzoo: क्यों 'self.quantity' को कुछ भी सेट करने की उम्मीद है बिलकुल भी? शायद आपको अपनी ऑब्जेक्ट्स बनाने वाले नियंत्रक कोड को शामिल करना चाहिए। कहीं आप एक पेय बना रहे हैं लेकिन यह नहीं बताते कि 'मात्रा' कितनी मात्रा है, इसलिए मात्रा 'शून्य' है –

+0

मैंने पेय नियंत्रक और माइग्रेशन डाला है। कुल_माउंट विधि – blawzoo

संबंधित मुद्दे