在选择表单中传递变量以进行预选(Ruby on rails)

时间:2010-11-04 06:06:59

标签: ruby-on-rails ruby

我正在阅读AROR书中的例子:  http://media.pragprog.com/titles/rails3/code/e1/views/app/views/test/select.rhtml

<% @user = "cat"

def @user.id
 4
 end

<% form_for :user do |form| %>
  <%= form.select(:name, %w{ Andy Bert Chas Dave Eric Fred }) %>
<% end %>

在这个例子中,看起来@ user.id被硬编码返回4.我尝试了类似的东西:

@temp = 4

def @user.id
  @temp
end

这不起作用......如何为此特定函数返回非全局变量?

2 个答案:

答案 0 :(得分:1)

你必须明白,当你做“def @ user.id”时,你实际上是在与@user对象相关联的单例类上定义一个方法(单例类也被称为“本征类”或“影子类”) )。所以正在做的就是这个:

@temp = 4

class << @user
  def id
    @temp
  end
end

如上所示,id方法定义中的@temp是一个常规实例变量,但它与singleton类相关联。换句话说,id定义中的@temp与@temp外部不同。您可以通过直接设置内部@temp来处理这个问题,如下所示:

@user.instance_variable_set(:@temp, 4)

def @user.id
  @temp
end

如果这有帮助,请告诉我,或者您对单身人士课程的工作方式有任何疑问。

答案 1 :(得分:0)

这个问题实际上与表单无关,甚至与Ruby on Rails无关。这是纯粹的Ruby。

def @user.id; end是一种所谓的单例方法(您可以阅读更多关于here的内容)。现在,默认情况下,无法在单例方法中访问实例变量(例如@temp)。

有一些方法可以解决这个问题,但除非你特别想在视图中创建一个单例方法(为什么会这样?),我建议另一种设置预选值的方法。在您的示例中,它应该如下所示:

<% form_for :user do |form| %>
  <%= form.select(:name, %w{ Andy Bert Chas Dave Eric Fred }, {:selected => @temp}) %>
<% end %>

作为旁注; @var是Ruby中的实例变量 - 不是全局变量。全局变量以美元符号($var)开头,但除非您知道自己在做什么,否则请不要使用它。