Rails 使用什么 Ruby 技术使我的控制器方法呈现视图? [英] What Ruby technique does Rails use to make my controller methods render views?

查看:35
本文介绍了Rails 使用什么 Ruby 技术使我的控制器方法呈现视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是好奇是否有人知道在 Rails 框架中使用什么 Ruby 技术来完成以下任务.

Just curious if anybody knows what Ruby technique is used to accomplish the following in the Rails framework.

如果我不在 Rails 控制器上编写 index 方法,如果 URL 匹配该路由,Rails 仍将呈现索引视图文件.这是有道理的,因为我的控制器继承自一个父类,它必须有自己的 index 方法.

If I don't write, say, an index method on a Rails controller, Rails will still render the index view file if the URL matches that route. That makes sense, because my controller inherits from a parent class, which must have its own index method.

但是,如果我确实定义了一个 index 方法,并且只告诉它设置一个实例变量,它仍然会呈现适当的视图.例如:

However, if I do define an index method, and only tell it to set an instance variable, it still renders the appropriate view. For example:

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 才能获得该行为.

In pure Ruby, I would expect to have to call super to get that behavior.

我假设 Rails 使用某种元编程技术来保证我的控制器方法将调用 super.如果是这样,有人可以解释一下吗?您能指出执行此操作的源代码吗?

I assume that Rails uses some kind of metaprogramming technique to guarantee that my controller methods will call super. If so, can anyone explain it? Can you point to the source code that does this?

正如 Mladen Jablanović 指出的那样,我最初的心智模型是错误的;控制器方法通常不会渲染视图;相反,两者控制器方法视图渲染都由一些框架代码调用.这很明显,因为我可以使用任何名称创建控制器方法 - 例如,search - 并且 search 视图将被呈现.很明显,在这种情况下我没有覆盖父方法,一些框架代码正在解析控制器方法名称并寻找匹配的视图.

As Mladen Jablanović has pointed out, my initial mental model was wrong; the controller method doesn't normally render the view; instead, both the controller method and the view rendering are called by some framework code. This is apparent because I can make a controller method with any name - for example, search - and the search view will get rendered. So clearly I'm not overriding a parent method in that case, and some framework code is parsing the controller method name and looking for the matching view.

不过,框架必须能够检测控制器方法是否已经调用了render.所以这对我来说是另一个小秘密.

Still, the framework must be able to detect whether or not the controller method has already called render. So that's another small mystery to me.

推荐答案

在控制器上,有一个方法叫做 render_for_text.这需要一个字符串并将结果设置为响应正文.即使你不渲染为文本,渲染视图文件也会简单地读取文件的内容,对其进行评估,并将其传递给 render_for_text 方法.然后该方法将一个名为 @performed_render 的实例变量设置为 true,它告诉 rails 控制器已经渲染了一个视图.

On the controller, there is a method called render_for_text. This takes a string and sets the result as the response body. Even if you don't render as text, rendering a view file simply reads the file's contents, evaluates it, and passes it to the render_for_text method. The method then stores sets an instance variable called @performed_render to true, which tells rails that the controller has already rendered a view.

然后有一个方法叫做 performed? 表示渲染动作是否被调用.它通过检查 @performed_render@performed_redirect 是否为真来实现这一点.

There is then a method called performed? that indicates whether or not the render action has been called. It does this by checking if @performed_render or @performed_redirect is true.

有了以上信息,渲染方法的第一行现在应该有意义了,希望能回答你的问题:

With the above information, the very first line of the render method should make sense now, and hopefully answer your question:

引发 DoubleRenderError,如果执行,每个动作只能渲染或重定向一次"?

这篇关于Rails 使用什么 Ruby 技术使我的控制器方法呈现视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆