在html.erb中可以访问哪些控制器数据?

时间:2018-08-30 15:42:00

标签: ruby-on-rails model-view-controller erb

我试图了解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'

从概念上讲,为什么在{em> .html.erb 视图中可以访问@y,但为什么不能访问x

PS:我应该补充一点,我知道带有 @ 的变量表示Ruby中的实例变量,因此(我认为)@y将是{{1}实例的实例变量。 }。但是,我不清楚这将如何影响从SomeController访问的 .html.erb 视图文件。

5 个答案:

答案 0 :(得分:3)

在RoR中,如果您在控制器中将变量声明为实例变量@y,则它可用于视图。 另一方面,x是局部变量,只能在其范围内访问。

答案 1 :(得分:0)

根据您的示例,控制器中的@y与视图中的@y不同,但是从很高的层次看,它们似乎是相同的。 Rails在幕后做了很多魔术,如您所知(如果不知道), Rails相信约定优于配置,此时Rails将寻找所有{{1} },然后将其复制到instance variables,甚至假设您不需要它们,它就会在那里。 Rails将所有实例变量都暴露给各自的视图。 到目前为止,这是我的理解,如果我错过了什么,请添加更多详细信息。

答案 2 :(得分:0)

关于变量:

  • foo ='bar'#这意味着您声明了一个局部变量,该变量不能从视图中访问

  • @foo ='bar'#表示您声明了instance_variable,将在视图上显示

您还可以在执行并返回某些数据的控制器上定义helper_method,例如helpers

答案 3 :(得分:0)

根据上面的描述和答案,很明显,实例变量可以在视图中访问。

回答以下要点

  

从概念上讲,为什么在.html.erb视图中可以访问@y,但是x是   不是。

在渲染视图时,实例变量及其值将从控制器中获取并传递到视图初始化程序,后者将它们分配给视图实例。

这是使用以下红宝石方法完成的:

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 
  

[https://github.com/rails/rails/blob/0c5552a3dd28e35cce64462765cc41c5355db0f1/actionpack/lib/abstract_controller/rendering.rb#L138-L145][1]

在上面的链接中,名为

的方法
"view_assigns" -> collects the controller instance variable
"view_context passes" -> them to the views
"assign(new_assigns)" -> setting them in the view

答案 4 :(得分:0)

这是范围问题(范围定义了程序中变量可访问的位置)。 Ruby有四种类型的变量范围,localglobalinstanceclass

在您的情况下:

  • x是一个局部变量,对于声明它们的代码(方法,循环等)而言是局部的。
  • @y是一个实例变量,在定义该变量的类的实例中的任何位置都可见。

如果您明确将x设置为本地,则可以访问它:

def show
   render locals: {
      x:  1
   }
end

在视图中使用变量的推荐方法是使用instance variables。这是因为如果您尝试使用local variable而没有传递值,则会出现错误。但是使用instance variables,您将获得一个nil

有关如何在视图中使用local variables的更多信息,可以检查link