未定义 'items' 为零 class
undefined 'items' for nil class
在我的电子商店网站上,当我尝试结帐我的购物车时,我收到了
undefined method `items' for nil:NilClass.
虽然在错误页面
我知道我的购物车在那里...但是当我调用它时,它没有给我
购物车模型
class Cart
attr_reader :items
def self.build_from_hash hash
items = if hash["cart"] then
hash["cart"]["items"].map do |item_data|
CartItem.new item_data["product_id"], item_data["quantity"]
end
else
[]
end
new items
end
def initialize items = []
@items = items
end
def add_item product_id
item = @items.find { |item| item.product_id == product_id }
if item
item.increment
else
@items << CartItem.new(product_id)
end
end
def empty?
@items.empty?
end
def count
@items.length
end
def serialize
items = @items.map do |item|
{
"product_id" => item.product_id,
"quantity" => item.quantity
}
end
{
"items" => items
}
end
def total_price
@items.inject(0) { |sum, item| sum + item.total_price }
end
end
应用程序控制器
def initialize_cart
@cart = Cart.build_from_hash session
end
手推车控制器
class CartsController < ApplicationController
before_filter :initialize_cart
def add
@cart.add_item params[:id]
session["cart"] = @cart.serialize
product = Product.find params[:id]
redirect_to :back, notice: "Added #{product.name} to cart."
end
def show
end
def checkout
@order_form = OrderForm.new user: User.new
end
end
订单控制器
class OrdersController
def create
@order_form = OrderForm.new(
user: User.new(order_params[:user]),
cart: @cart
)
if @order_form.save
redirect_to '/', notice: "Thank you for placing your order."
@cart.empty?
else
render 'carts/checkout'
end
end
结帐视图
<div class="container-checkout">
<p class="text-title"> You are checking out the following: </p>
<table class="table table-striped">
<thead class="name-table">
<tr>
<td> Image </td>
<td> Name </td>
<td> Category</td>
<td> Size </td>
<td> Item Price </td>
</tr>
</thead>
<tbody>
<% @cart.items.each do |item| %>
<tr>
<td><img src="<%= item.product.image %>" width="50px"></td>
<td><%= item.product.name.capitalize %></td>
<td><%= item.product.category.name %></td>
<td><%= item.product.size %></td>
<td class="price-item"><%= number_to_currency item.total_price %>
</td>
<% end %>
</tr>
<tr class="total-price total-price-checkout">
<td class="name-table">Total Price</td>
<td class="price-item"><%= number_to_currency @cart.total_price %></td>
</tr>
</tbody>
</table>
</div>
<div class="details-user-form">
<%= form_for @order_form, url: orders_path do |f|%>
<% f.fields_for :user, @order_form.user do |u| %>
<p class="text-title">Fill the form with your details</p>
<p><%= render "orders/errors" %></p>
<p><%= u.text_field :name, placeholder: "Name" %></p>
<p><%= u.text_field :email, placeholder: "Email" %></p>
<p><%= u.text_field :address, placeholder: "Address" %></p>
<p><%= u.text_field :postal_code, placeholder: "Postal code" %></p>
<p><%= u.text_field :city, placeholder: "City" %></p>
<p><%= u.text_field :country, placeholder: "Country" %></p>
<%= f.submit "Place order", class: "order-btn"%><br>
<% end %>
<% end %>
</div>
知道为什么要这样做吗?也是因为,它以前工作过..我不知道为什么它停止了。
我认为问题可能是 @cart
变量没有在 OrdersController
中设置。在 CartsController
中设置变量不会使其在全局范围内可用,因为它只会作用于创建它的控制器,在您的例子中是 CartsController
。
此外,我发现您的 Cart
模型更像是一个虚拟模型,而不是 ActiveRecord
模型,我认为 ActiveRecord
已经具备了您正在寻找的行为您在那里重新创建了很多方法。
我不太确定,但我认为这些可能是问题所在。
更新
我想我发现了你的错误。
在你的 OrdersController
你应该有一个
before_action :initialize_cart
这似乎来自您的 ApplicationController
如果您检查 CartController
中的 checkout
方法,您会发现您没有设置 @cart
。因此,当您点击 checkout
视图时,它会在该方法中查找值或 @cart
。将它设置在那里,就像下面的代码应该清除你的错误。
def checkout
@order_form = OrderForm.new user: User.new
@cart = # cart object
end
在我的电子商店网站上,当我尝试结帐我的购物车时,我收到了
undefined method `items' for nil:NilClass.
虽然在错误页面
我知道我的购物车在那里...但是当我调用它时,它没有给我
购物车模型
class Cart
attr_reader :items
def self.build_from_hash hash
items = if hash["cart"] then
hash["cart"]["items"].map do |item_data|
CartItem.new item_data["product_id"], item_data["quantity"]
end
else
[]
end
new items
end
def initialize items = []
@items = items
end
def add_item product_id
item = @items.find { |item| item.product_id == product_id }
if item
item.increment
else
@items << CartItem.new(product_id)
end
end
def empty?
@items.empty?
end
def count
@items.length
end
def serialize
items = @items.map do |item|
{
"product_id" => item.product_id,
"quantity" => item.quantity
}
end
{
"items" => items
}
end
def total_price
@items.inject(0) { |sum, item| sum + item.total_price }
end
end
应用程序控制器
def initialize_cart
@cart = Cart.build_from_hash session
end
手推车控制器
class CartsController < ApplicationController
before_filter :initialize_cart
def add
@cart.add_item params[:id]
session["cart"] = @cart.serialize
product = Product.find params[:id]
redirect_to :back, notice: "Added #{product.name} to cart."
end
def show
end
def checkout
@order_form = OrderForm.new user: User.new
end
end
订单控制器
class OrdersController
def create
@order_form = OrderForm.new(
user: User.new(order_params[:user]),
cart: @cart
)
if @order_form.save
redirect_to '/', notice: "Thank you for placing your order."
@cart.empty?
else
render 'carts/checkout'
end
end
结帐视图
<div class="container-checkout">
<p class="text-title"> You are checking out the following: </p>
<table class="table table-striped">
<thead class="name-table">
<tr>
<td> Image </td>
<td> Name </td>
<td> Category</td>
<td> Size </td>
<td> Item Price </td>
</tr>
</thead>
<tbody>
<% @cart.items.each do |item| %>
<tr>
<td><img src="<%= item.product.image %>" width="50px"></td>
<td><%= item.product.name.capitalize %></td>
<td><%= item.product.category.name %></td>
<td><%= item.product.size %></td>
<td class="price-item"><%= number_to_currency item.total_price %>
</td>
<% end %>
</tr>
<tr class="total-price total-price-checkout">
<td class="name-table">Total Price</td>
<td class="price-item"><%= number_to_currency @cart.total_price %></td>
</tr>
</tbody>
</table>
</div>
<div class="details-user-form">
<%= form_for @order_form, url: orders_path do |f|%>
<% f.fields_for :user, @order_form.user do |u| %>
<p class="text-title">Fill the form with your details</p>
<p><%= render "orders/errors" %></p>
<p><%= u.text_field :name, placeholder: "Name" %></p>
<p><%= u.text_field :email, placeholder: "Email" %></p>
<p><%= u.text_field :address, placeholder: "Address" %></p>
<p><%= u.text_field :postal_code, placeholder: "Postal code" %></p>
<p><%= u.text_field :city, placeholder: "City" %></p>
<p><%= u.text_field :country, placeholder: "Country" %></p>
<%= f.submit "Place order", class: "order-btn"%><br>
<% end %>
<% end %>
</div>
知道为什么要这样做吗?也是因为,它以前工作过..我不知道为什么它停止了。
我认为问题可能是 @cart
变量没有在 OrdersController
中设置。在 CartsController
中设置变量不会使其在全局范围内可用,因为它只会作用于创建它的控制器,在您的例子中是 CartsController
。
此外,我发现您的 Cart
模型更像是一个虚拟模型,而不是 ActiveRecord
模型,我认为 ActiveRecord
已经具备了您正在寻找的行为您在那里重新创建了很多方法。
我不太确定,但我认为这些可能是问题所在。
更新
我想我发现了你的错误。
在你的 OrdersController
你应该有一个
before_action :initialize_cart
这似乎来自您的 ApplicationController
如果您检查 CartController
中的 checkout
方法,您会发现您没有设置 @cart
。因此,当您点击 checkout
视图时,它会在该方法中查找值或 @cart
。将它设置在那里,就像下面的代码应该清除你的错误。
def checkout
@order_form = OrderForm.new user: User.new
@cart = # cart object
end