Rails实例变量不在ApplicationController和app / helpers

时间:2016-08-06 17:50:06

标签: ruby-on-rails helper instance-variables

我有一个我在控制器中设置的实例变量。

@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设计。我认为实例变量类似于全局变量,但显然不是。

感谢您的帮助。

1 个答案:

答案 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而不是重新分配它来躲避这些问题,但我发现视图助手可能会像这样令人惊讶地改变状态。