我试图了解如何连接Rails中的控制器类和.html.erb视图文件,以及视图如何访问控制器方法中的数据。例如,我有以下控制器类:
class SomeController < ApplicationController
def show
# defining some data to access in the view
x = 1
@y = 2
end
end
如果在相应的.html.erb视图文件中,我尝试访问@y
,这很好用
<p> <%= @y %> </p>
但是,如果我尝试访问x
,则会出错
<p> <%= x %> </p>
未定义的局部变量或方法'x'
从概念上讲,为什么@y
可以在.html.erb视图中访问,但x
不是。
PS:我应该补充一点,我知道变量用@表示Ruby中的实例变量,所以(我认为)@y
将是SomeController
实例的实例变量。但是,我不清楚这是如何影响.html.erb视图文件可以从SomeController
访问的。
根据上面提到的描述和答案,很明显可以在视图中访问实例变量。
回答下面提到的问题
从概念上讲,为什么@y可以在.html.erb视图中访问,但x不是。
在渲染视图时,实例变量及其值从控制器中获取并传递给视图初始化程序,后者将它们分配给视图实例。
这是使用这些ruby方法完成的:
instance_variables - gets names of instance variables
instance_variable_get(variable_name) - gets value of an instance variable
instance_variable_set(variable_name, variable_value) - sets value of an instance variable
在上面的链接中命名的方法
"view_assigns" -> collects the controller instance variable
"view_context passes" -> them to the views
"assign(new_assigns)" -> setting them in the view
在RoR中,如果您将控制器中的变量声明为实例变量@y
,则它可供您的视图使用。另一方面,x
是局部变量,只能在其范围内访问。
根据你的例子,控制器中的@y
在视图中不是相同的@y
,但是在非常高的层次上看起来它们是相同的。 Rails在引擎盖下做了很多魔术,正如你已经知道的那样(如果不是),Rails相信约会配置,此时Rails
将寻找instance variables
中的所有controller
并将它们复制到views
,甚至让我们说你不想要它们,它会在那里。 Rails将所有实例变量暴露给相应的视图。到目前为止,这是我的理解,如果我错过了什么,请添加更多细节。
关于变量:
instance_variable
,这将在视图中可用您还可以在控制器上定义helper_method
,执行并返回一些数据,如helpers
。
这是范围问题(范围定义了程序中可访问变量的位置)。 Ruby有四种类型的变量范围,local
,global
,instance
和class
。
在你的情况下:
x
是一个局部变量,它们是声明它们的代码(方法,循环等)的本地变量。@y
是一个实例变量,它们在已定义它的类的实例中的任何位置都可见。如果您明确地将其设置为本地,则可以访问x
:
def show
render locals: {
x: 1
}
end
在视图中使用变量的推荐方法是使用instance variables
。那是因为如果你试图使用local variable
而你没有传入一个值,你会得到一个错误。但是使用instance variables
,你会得到一个nil
。
有关如何在视图中使用local variables
的更多信息,您可以查看link。