为何current_spree_user在Solidus/Spree视图中可用且非实例变量?
current_spree_user能在Solidus/Spree视图中直接使用? 嘿,这个问题问得特别好!我来给你理清楚current_spree_user不用定义成实例变量就能在视图里用的原因:
它是Spree/Solidus内置的视图辅助方法
Spree/Solidus底层依赖Devise做用户身份验证,Devise本身会提供current_user这个核心方法,而Spree在此基础上封装了current_spree_user——本质上这是一个视图辅助方法(helper method)。Rails的机制会自动把所有注册的helper方法导入到视图环境中,所以你不用手动声明就能直接调用,就像用link_to、number_to_currency这些Rails内置helper一样自然。它的定义与全局可用的原理
你可以在Spree的源码里找到这个方法的实现,通常在spree/core/controller_helpers/auth.rb这类文件中,大概逻辑是这样的:def current_spree_user @current_spree_user ||= Spree::User.find_by(id: session[:spree_user_id]) || Spree::User.new end这个方法会被Spree通过Rails的
helper机制,混入到所有控制器和视图的上下文里。也就是说,不管你在哪个控制器对应的视图里,都能直接调用这个方法。内部缓存的小细节
方法里的@current_spree_user是用来做结果缓存的——第一次调用时会查数据库或者生成新用户对象,之后再调用就直接用缓存的实例变量,避免重复查询。但我们在视图里调用的是current_spree_user这个方法,而不是直接访问@current_spree_user实例变量,这就是为什么不用加@也能正常使用的关键。
简单总结:current_spree_user是Spree为Devise身份验证封装的全局视图辅助方法,靠Rails的helper机制实现视图内直接调用,不需要手动定义成局部或实例变量~
内容的提问来源于stack exchange,提问作者Paul Verschoor

