56

在我的 Rails 应用程序中,我有一个这样的控制器:

class MyController < ApplicationController
  def show
    @blog_post = BlogPost.find params[:id]
  end
end

在我看来,我可以简单地这样做:

<%= @blog_post.title %>

我对魔法感到不舒服。这是如何实现的?

4

2 回答 2

91

当视图被渲染时,实例变量和它们的值从控制器中被拾取并传递给视图初始化器,视图初始化器将它们设置为视图实例。这是使用这些 ruby​​ 方法完成的:

instance_variables- 获取实例变量的名称(文档instance_variable_get(variable_name)- 获取实例变量的值(文档instance_variable_set(variable_name, variable_value)- 设置实例变量的值(文档

这是 Rails 代码:

收集控制器实例变量(github):

def view_assigns
  hash = {}
  variables  = instance_variables
  variables -= protected_instance_variables
  variables -= DEFAULT_PROTECTED_INSTANCE_VARIABLES
  variables.each { |name| hash[name[1..-1]] = instance_variable_get(name) }
  hash
end

将它们传递给视图(github):

def view_context
  view_context_class.new(view_renderer, view_assigns, self)
end

在视图中设置它们(github):

def assign(new_assigns) # :nodoc:
  @_assigns = new_assigns.each { |key, value| instance_variable_set("@#{key}", value) }
end
于 2013-09-17T17:07:48.340 回答
-3

体面的曝光gem 是 Rails 的标准控制器实例变量行为的替代品。自述文件对这个问题有很好的描述。

于 2015-05-06T05:00:23.050 回答