我的“新”操作从会话中生成购物车对象@cart。当我通过AJAX调用“更新”操作时,@ cart对象不存在。为什么不跨控制器共享它?
cart_controller.rb
def new
@cart = Cart.new(session[:cart])
end
def update
logger.debug @cart.present? # false
end
答案 0 :(得分:3)
@cart
是一个实例变量,在请求之间不会保留。 session
在两次请求之间是可访问的。
基本上,如果您在会话中设置了一些数据,则可以在请求之间使用该数据。如前所述,您可以在执行before_filter
操作之前设置@cart
和预设update
实例变量。
class MyController < ApplicationController
before_action :instantiate_cart, only: [:update] #is the list of actions you want to affect with this `before_action` method
...
private
def instantiate_cart
@cart = Cart.new(session[:cart])
end
end
答案 1 :(得分:1)
实例变量(以@
开头)在请求之间(或在控制器操作之间)不共享。您可以表示一种获取购物车的方法。这是一个示例:
def new
cart
end
def update
logger.debug cart.present?
end
private
def cart
@cart ||= Cart.new(session[:cart])
end
答案 2 :(得分:0)
实例变量不能在控制器之间共享。它们可用于定义它们的actions
。因此,由于未定义@cart
操作,因此无法使用update
。
def new
@cart = Cart.new(session[:cart])
end
def update
@cart = Cart.new(session[:cart])
logger.debug @cart.present?
end
要 DRY 代码,请使用before_action
设置购物车
before_action :set_cart, only: [:new, :update]
def new
end
def update
logger.debug @cart.present?
end
private
def set_cart
@cart = Cart.new(session[:cart])
end
答案 3 :(得分:0)
TL; DR:随着每个请求创建一个新的控制器实例,控制器实例变量不会在不同的HTTP请求之间共享。
从概念上讲,您所期望的应该是正确的!您正在定义实例变量,并且应该在类中的任何地方都可以访问它。
问题在于,在每个HTTP请求上,都将创建该类的新实例。
因此,当您执行new
操作时,将启动控制器实例,将调用new
方法,并创建和分配@cart
。像这样:
# HTTP request /new
controller = MyController.new # an object of your controller is created
controller.new # the requested action is called and @cart is assigned
但是,当您向update
发出新的HTTP请求时,将启动控制器的新实例,将调用update
方法,并且该方法没有@cart
!
# HTTP request /update
controller1 = MyController.new # an object of your controller is created
controller1.new # the requested action is called and @cart is not assigned
您可以看到controller
和controller1
是从MyController
发起的两个不同的对象,因为这发生在两个不同的HTTP请求(不同的上下文)中。
要解决您的问题,您需要在需要执行以下操作时为每个操作创建@cart
:
def new
cart
end
def update
logger.debug cart.present?
end
private
def cart
@cart ||= Cart.new(session[:cart])
end