我正在阅读“使用Rails进行敏捷Web开发 - 实用指南”一书。在迭代C1上,创建一个购物车,我收到以下错误:
self.hotlineViewHeightConstraint.constant = 0.0f;
以下是源文件:
的routes.rb
NoMethodError in StoreController#display_cart
undefined method `items' for #<Hash:0xb5cf041c>
Extracted source (around line #15):
13 def display_cart
14 @cart = find_cart
15 @items = @cart.items
16 end
17
18 private
store_controller.rb
Rails.application.routes.draw do
get 'store' => 'store#index'
get 'add_item_to_cart' => 'store#add_to_cart'
get 'display_cart' => 'store#display_cart'
resources :products
cart.rb
class StoreController < ApplicationController
def index
@products = Product.salable_items
end
def add_to_cart
product = Product.find(params[:id])
@cart = find_cart
@cart.add_product(product)
redirect_to display_cart_path
end
def display_cart
@cart = find_cart
@items = @cart.items
end
private
def find_cart
session[:cart] ||= Cart.new
end
end
line_item.rb
class Cart
attr_reader :items
attr_reader :total_price
def initialize
@items = []
@total_price = 0.0
end
def items
@items
end
def add_product(product)
@items << LineItem.for_product(product)
@total_price += product.price
end
end
我从class LineItem < ActiveRecord::Base
belongs_to :product
def self.for_product(product)
item = self.new
item.quantity = 1
item.product = product
item.unit_price = product.price
item
end
end
的{{1}}行动中找到了display_cart
行动。即使add_to_cart
中有StoreController
,为什么我会收到def items
?
答案 0 :(得分:1)
问题在于
def find_cart
session[:cart] ||= Cart.new
end
您的session[:cart]
是一个哈希,因此无法获得Cart.new
,当您致电@cart.items
时,Hash
就会调用Cart
而不是{{1}}对象
答案 1 :(得分:1)
在你的display_cart方法中:你正在做@cart = find_cart
,它可能会返回一个哈希而不是一个对象,就像你正在进行的session[:cart] ||= Cart.new
的find_cart方法一样,它可能会返回一个哈希。
答案 2 :(得分:1)
假设您已在会话中存储了购物车ID,您可以在方法中执行以下更改
def find_cart
Cart.find_by_id(session[:cart_id]) ||= Cart.new
end
答案 3 :(得分:1)
尝试此操作以返回您的购物车实例:
def find_cart
Cart.find(session[:cart]
rescue ActiveRecord::RecordNotFound
cart = Cart.new
session[:cart] = cart.id
end
这几乎与您书中的代码相同。在语义上你可以调用该函数current_cart
。
通过仅存储购物车ID并使用ActiveRecord find()
方法,通过调用Cart.new
进行救援,您将始终返回购物车实例。
修改强>
如果你没有将Cart作为模型实现,你将(逻辑上)永远不能实例化它的对象。
This是关于在Ruby on Rails中处理会话的好文章。正如您将看到的,会话本身就是一个“自然”的哈希,你会发现一些替代解决方案,用于在rails应用程序中存储会话。