只是好奇是否有人知道在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 16: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 14:49:26
在呈现视图时,Rails使用控制器中实例变量的副本初始化适当视图模板的实例。因此,实例变量实际上不是由视图继承的,而是在视图呈现之前从控制器复制到视图中。
我还没有在源代码中查到确切的细节,但是上面的解释至少应该概述一下它是如何工作的。
发布于 2010-12-20 14:58:05
Jamis在几年前写了很多关于隐式路由的文章,这里。
我相信你要找的代码在资源里。Rails查看入站请求,如果没有指定控制器和操作(对于RESTful路由)。
更新:控制器是Rails框架的一个非常复杂的部分。它并不像拥有单个方法的单个Ruby类那么简单(这就是为什么并不真正需要super,但是在调用单个方法之前和之后都会进行一系列调用。
Rack处理请求并将其传递给执行路由的Rails,为操作委托给ActionController实例(您可能已经或没有对其进行编码),然后将结果传递给呈现过程。
https://stackoverflow.com/questions/4490508
复制相似问题