2016-08-16 9 views
1

Ich habe andere Fragen ähnlich zu diesem gesehen, aber keine, die genau die gleichen sind (ich bin immer noch ein wenig Anfänger). Wenn es einen anderen Thread gibt, der derselbe ist, lass es mich wissen! Vielen Dank!!Nil kann nicht in BigDecimal gezwungen werden - Ruby On Rails

UPDATE: Ich habe vergessen, diesen Code hinzuzufügen. Was ist eine Migrationsdatei, um die Menge hinzuzufügen?

class AddQuantityToProductItems < ActiveRecord::Migration[5.0] 
    def change 
    add_column :product_items, :quantity, :integer, default: 1 
    end 
end 

Ich erhalte den Fehler aus dem unten stehenden Code "Null kann nicht in BigDecimal gezwungen werden" (ProductItem Modell:)

class ProductItem < ApplicationRecord 
    belongs_to :product 
    belongs_to :cart 

    def total_price 
    product.price * quantity 
    end 
end 

Hier ist das Wagen Modell:

class Cart < ApplicationRecord 
    has_many :product_items, dependent: :destroy 

    def add_product(product_id) 
    current_item = product_items.find_by(product_id: product_id) 
    if current_item 
     current_item.quantity += 1 
    else 
     current_item = product_items.build(product_id: product_id) 
    end 
    current_item 
    end 

    def total_price 
    product_items.to_a.sum{|item| item.total_price} 
    end 
end 

class Product < ApplicationRecord 
    before_destroy :ensure_not_product_item 
    has_many :product_items 
    validates :title, :description, presence: true 
    validates :price, numericality: {greater_than_or_equal_to: 0.01} 
    validates :title, uniqueness: true 
    has_attached_file :image, styles: { medium: "300x300>", thumb:  "100x100>" } 
    validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/ 

    def ensure_not_product_item 
    if product_items.empty? 
     return true 
    else 
     errors.add(:base, 'Product Items') 
     return false 
    end 
    end 
end 

ProductItems Controller:

class ProductItemsController < ApplicationController 

    include CurrentCart 
    before_action :set_cart, only: [:create] 
    before_action :set_product_item, only: [:show, :destroy] 

    def create 
    product = Product.find(params[:product_id]) 
    @product_item = @cart.add_product(product.id) 
    if @product_item.save 
     redirect_to shop_url, notice: 'Your Product was added to the cart!' 
    else 
     render :new 
    end 
    end 

    private 

    def set_product_item 
    @product_item = ProductItem.find(params[:id]) 
    end 

    def product_item_params 
    params.require(:product_item).permit(:product_id) 
    end 

end 

-Code für Produkt Artikel und Produkte aus schema.rb

create_table "product_items", force: :cascade do |t| 
    t.integer "product_id" 
    t.integer "cart_id" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    t.integer "quantity" 
    t.index ["cart_id"], name: "index_product_items_on_cart_id" 
    t.index ["product_id"], name: "index_product_items_on_product_id" 
end 

create_table "products", force: :cascade do |t| 
    t.string "title" 
    t.string "image" 
    t.text  "description" 
    t.decimal "price" 
    t.datetime "created_at",   null: false 
    t.datetime "updated_at",   null: false 
    t.string "image_file_name" 
    t.string "image_content_type" 
    t.integer "image_file_size" 
    t.datetime "image_updated_at" 
end 

Wenn andere Dateien benötigt werden, werde ich sie gern veröffentlichen . Ich bin mir sicher, dass es etwas sehr Einfaches ist, ich kann es einfach nicht herausfinden. Vielleicht versuche ich zu sehr, das Problem zu finden. Lol. Danke, dass Sie sich die Zeit genommen haben, uns zu helfen!

+0

Das einzige, was Sie vermissen, ist der Text des Fehlers. Es enthält einen Dateinamen und eine Zeilennummer, um anzuzeigen, woher es kommt. –

Antwort

1

Von den Klängen der es, Sie initialisieren nicht die quantity Attribut, wenn Sie ein neues Produkt erstellen.

könnten Sie entweder initialisieren quantity Attribut in der durch Zugabe eines after_initialize Block in ProductItem

class ProductItem < ApplicationRecord 
    after_initialize do 
    self.quantity ||= 1 
    end 
end 

Oder Sie das quantity Attribut in der Cart#add_product Methode einstellen könnte, wenn Sie ein Produkt, Artikel zu erstellen:

class Cart < ApplicationRecord 
    def add_product(product_id) 
    current_item = product_items.find_by(product_id: product_id) 
    if current_item 
     current_item.quantity += 1 
    else 
     # initialize the quantity value when creating a new item 
     current_item = product_items.build(product_id: product_id, quantity: 1) 
    end 
    current_item 
    end 
end 

Eine andere Methode wäre, einen Standardwert in der ProductItem#total_price Methode zu setzen:

class ProductItem < ApplicationRecord 
    def total_price 
    product.price * (quantity || 1) 
    end 
end 

Persönlich würde ich mit after_initialize Methode gehen, wie es die konsequenteste Option ist, dass die quantityimmer einen Wert hat.

+0

Ich habe vergessen, den Code hinzuzufügen, aber ich habe es gerade aktualisiert. Ich habe den Standardwert der Menge in der Migrationsdatei festgelegt. Nicht sicher, ob das ändert, was ich tun muss oder nicht. – Logan

+0

Der Standardwert für die Datenbank spielt in gewisser Hinsicht keine Rolle, da das neue Objekt, das mit 'build' oder' new' erstellt wurde, erst dann den Wert * database * erhält, wenn Sie den Datensatz speichern und dann erneut abrufen. – br3nt

+2

Ich habe die after_initialize-Methode verwendet. Es funktioniert perfekt. Und, ja, das macht Sinn. Vielen Dank für Ihre Antwort. Ich habe keine Ahnung, warum ich das nicht einfach herausgefunden habe. Es war so einfach. Ich glaube, ich habe mir so lange den Kopf zerbrochen, weil ich versucht habe, mir einen komplexen Grund dafür zu überlegen, warum es so passiert ist, dass ich es schließlich überlastet habe. Haha. Danke noch einmal! – Logan

0

Ihr Code versucht Arithmetik mit einem nil Wert, also die Nachricht nil can't be coerced into BigDecimal.

Warum dies passiert, müssen Sie etwas graben, um herauszufinden, wo im Code der Fehler auftritt. Ein Anhaltspunkt ist, dass der Fehler impliziert der nil Wert ist auf der rechten Seite der Operation, zB:

bd = BigDecimal.new("0") 
bd + nil # => nil can't be coerced into BigDecimal 

im Gegensatz zu:

nil + bd # => undefined method '+' for nil:NilClass