如果有人知道在Rails框架中使用什么Ruby技术来完成以下内容,那就太好了。
如果我没有在Rails控制器上编写index
方法,如果URL匹配该路由,Rails仍将呈现索引视图文件。这是有道理的,因为我的控制器继承自父类,父类必须有自己的index
方法。
但是,如果我执行定义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
。如果是这样,有人可以解释一下吗?你能指出执行此操作的源代码吗?
正如MladenJablanović指出的那样,我最初的心理模型是错误的;控制器方法通常不呈现视图;相反,两者控制器方法和视图呈现由某些框架代码调用。这很明显,因为我可以创建一个具有任何名称的控制器方法 - 例如search
- 并且search
视图将被渲染。很明显,在这种情况下,我没有覆盖父方法,并且一些框架代码正在解析控制器方法名称并寻找匹配的视图。
但是,框架必须能够检测控制器方法是否已调用render
。这对我来说是另一个小谜。
答案 0 :(得分:6)
在控制器上,有一个名为render_for_text
的方法。这需要一个字符串并将结果设置为响应主体。即使您不渲染为文本,渲染视图文件也只是读取文件的内容,对其进行评估,然后将其传递给render_for_text
方法。然后,该方法将名为@performed_render
的实例变量存储到true
,告知rails控制器已经呈现了视图。
然后有一个名为performed?
的方法,指示是否已调用渲染动作。它通过检查@performed_render
或@performed_redirect
是否为真来完成此操作。
根据以上信息,very first line of the render method现在应该有意义,希望能回答您的问题:
raise DoubleRenderError, "Can only render or redirect once per action" if performed?
答案 1 :(得分:1)
在渲染视图时,Rails使用控制器中的实例变量副本初始化相应视图模板的实例。因此,实例变量实际上并不是由视图继承的,而是在呈现视图之前从控制器复制到视图中。
我没有查看源代码中的确切细节,但上述解释至少应概述其工作原理的一般概念。
答案 2 :(得分:1)