我有一个我在控制器中设置的实例变量。
@cost=[1,2,3]
最终调用一个视图调用一个部分,然后调用app / helpers中的一个帮助器。
在调试器中,当我输入辅助方法时,我可以看到@cost仍为[1,2,3]。
在helper方法中,我将@cost设置为[4,5,6],然后调用application_controller.rb中定义的辅助方法set_cost。
class ApplicationController < ActionController::Base
helper_method :set_cost
def set_cost
@cost=[7,8,9]
end
end
当我输入set_cost时,我可以在调试器中看到@cost已恢复为[1,2,3]。
当我回到app / helpers中的helper方法时,我可以在调试器中看到@cost不再是[7,8,9],但已恢复为[4,5,6]。
如果我直接从控制器调用set_cost,当控制器返回控制器时@cost为[7,8,9]。
有没有办法可以在app / helpers中的控制器,视图,部分,辅助方法和application_controller.rb中的辅助方法中访问和操作实例变量,以使引用/值保持一致?好像它正在改变范围并制作变量的本地版本。
我意识到将@cost传递给set_cost可能有设计和实际好处(我的实际函数比我显示的更复杂),更新它,然后将其返回到原始函数以进行赋值,但即使如此实现我想要的,我想更好地理解Rails设计。我认为实例变量类似于全局变量,但显然不是。
感谢您的帮助。
答案 0 :(得分:1)
实例变量不是全局变量 - 它与特定实例(因此名称)相关联。
Rails允许您从视图中访问控制器实例变量。这通过复制控制器实例变量来工作:AbstractController::Rendering中的view_assigns
方法创建了所有实例变量的哈希。稍后,视图对象将该哈希值用于recreate实例变量。当你说它就好像有变量的本地副本一样时,那就是发生的事情。
值是共享的,即最初在视图和控制器@cost.object_id
中都是相同的。如果你的帮助者要做@cost.replace(...)
这样的事情,那么你会看到所有地方的变化,但是当你重新分配@cost
时,分配不会影响控制器(反之亦然) - 控制器实例变量的副本到视图是一次性操作。)
“普通”助手最终成为视图上下文的实例方法,但helper_method
创建的是控制器实例方法 - rails基本上定义了一个看起来像
def set_cost
controller.set_cost
end
你可以通过改变@cost而不是重新分配它来躲避这些问题,但我发现视图助手可能会像这样令人惊讶地改变状态。