我已经看到了与此类似的其他问题,但没有一个完全相同(我还是有点初学者)。如果有另一个相同的线程,请告诉我!谢谢!
更新 我忘了添加此代码。哪个是用于添加数量的迁移文件。
class AddQuantityToProductItems < ActiveRecord::Migration[5.0]
def change
add_column :product_items, :quantity, :integer, default: 1
end
end
我从下面的代码中继续收到错误“nil无法强制转换为BigDecimal”( ProductItem Model:)
class ProductItem < ApplicationRecord
belongs_to :product
belongs_to :cart
def total_price
product.price * quantity
end
end
以下是购物车型号:
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
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
如果需要任何其他文件,我很乐意发布它们。我确定这很简单,我似乎无法弄明白。也许我很难找到问题。大声笑。 感谢您抽出宝贵时间提供帮助!
答案 0 :(得分:1)
根据它的声音,您在创建新产品项时没有初始化quantity
属性。
您可以通过在quantity
after_initialize
块来初始化ProductItem
属性
class ProductItem < ApplicationRecord
after_initialize do
self.quantity ||= 1
end
end
或者,您可以在创建产品项时在quantity
方法中设置Cart#add_product
属性:
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
另一种方法是在ProductItem#total_price
方法中设置默认值:
class ProductItem < ApplicationRecord
def total_price
product.price * (quantity || 1)
end
end
就个人而言,我会使用after_initialize
方法,因为它是最一致的选项,因为quantity
始终有值。
答案 1 :(得分:0)
您的代码正在尝试使用nil
值进行算术运算,因此消息nil can't be coerced into BigDecimal
。
至于为什么会发生这种情况,您需要进行一些挖掘,以找出错误出现在代码中的哪个位置。一个线索是错误意味着nil
值位于操作的右侧,例如:
bd = BigDecimal.new("0")
bd + nil # => nil can't be coerced into BigDecimal
而不是:
nil + bd # => undefined method '+' for nil:NilClass