如何在控制器中的实例变量可用于Rails中的视图

时间:2011-12-16 00:24:01

标签: ruby-on-rails ruby ruby-on-rails-3 binding metaprogramming

我已经做了一段时间的Rails并且刚刚开始深入研究Rails从中获取力量的Ruby元编程。我真的无法想出这一个,它让我发疯。如何在控制器中的实例变量可用于Rails中的视图(与视图共享)?我知道它背后有一些元编程魔术,但我无法理解。请提前感谢你的所有帮助。

1 个答案:

答案 0 :(得分:7)

更新:原始接受的答案错误

我现在要离开它,以证明我是多么的错。经过足够的投票后,我决定调查一下这实际上是如何运作的。我的原始答案是在我对rails非常新的之后编写的,并且是基于我使用过的其他MVC库(特别是CodeIgniter)的假设。

它是如何工作的(从Rails 4开始)

AbstractController(其中ActionController::Base包含且您的ApplicationController继承自)包含一个名为view_assigns的方法。此方法从控制器的上下文中获取所有(未受保护的)实例变量,并以散列形式返回它们。此方法由ActionView::Basehere)的实例使用。

因此,基本上,实例变量通过一些元编程魔法通过哈希提供给您的视图。您的视图绝对不会在控制器的上下文或范围内执行。这就是为什么必须将控制器方法显式声明为辅助方法以使它们对视图可见的原因。该功能由单独的元编程层启用。

原文(错误)答案:

这不是那么复杂或“元”。 ActionController#render方法在当前ApplicationController实例的范围内执行模板代码(erb,haml,无论如何)。这意味着模板中的所有代码都在ApplicationController内的方法内执行,因此可以访问它在其中执行的对象的实例变量。

如果您不致电render,那么ApplicationController将尝试根据操作名称确定要调用render的模板。