只是好奇是否有人知道在Rails框架中使用什么Ruby技术来完成下面的任务。
如果我不在Rails控制器上编写index
方法,那么Rails仍然会呈现索引视图文件,如果该路径与该路径匹配的话。这是有意义的,因为我的控制器继承自父类,父类必须有自己的index
方法。
但是,如果我do定义了一个index
方法,并且只告诉它设置一个实例变量,它仍然呈现适当的视图。例如:
def index
@weasels = Weasel.all
# If I omit this line, Rails renders the index anyway.
# If this behavior is defined in the parent class's index method,
# it seems that by overriding the method, my index wouldn't do it.
# I'm not explicitly calling super to get the method from
# ActionController::Base, but maybe Rails is doing something like that?
render :index
end
在纯Ruby中,我希望必须调用super
才能得到这种行为。
我假设Rails使用某种元编程技术来保证我的控制器方法将调用super
。如果是的话,有人能解释吗?你能指出这样做的源代码吗?
更新
正如Mladenć所指出的,我最初的心智模型是错误的;控制器方法通常不会呈现视图;相反,--控制器方法和--视图呈现都是由一些框架代码调用的。这一点很明显,因为我可以使用任何名称(例如,search
)创建一个控制器方法,而search
视图将被呈现。因此很明显,在这种情况下,我没有重写父方法,一些框架代码正在解析控制器方法名称并查找匹配的视图。
但是,框架必须能够检测控制器方法是否已经调用了render
。所以这对我来说是另一个小秘密。
发布于 2010-12-20 08:47:25
在控制器上,有一个名为render_for_text
的方法。这将接受一个字符串,并将结果设置为响应体。即使不呈现为文本,呈现视图文件也只是读取文件的内容、计算它并将其传递给render_for_text
方法。然后,该方法将一个名为@performed_render
的实例变量存储到true
,它告诉rails控制器已经呈现了一个视图。
然后有一个名为performed?
的方法,它指示是否调用了呈现操作。它通过检查@performed_render
或@performed_redirect
是否为真来做到这一点。
有了上述信息,呈现方法的第一行现在应该是有意义的,并希望回答您的问题:
raise DoubleRenderError, "Can only render or redirect once per action" if performed?
发布于 2010-12-20 06:49:26
在呈现视图时,Rails使用控制器中实例变量的副本初始化适当视图模板的实例。因此,实例变量实际上不是由视图继承的,而是在视图呈现之前从控制器复制到视图中。
我还没有在源代码中查到确切的细节,但是上面的解释至少应该概述一下它是如何工作的。
https://stackoverflow.com/questions/4490508
复制