无法在Ruby on Rails控制器上填充哈希值

时间:2013-06-06 06:01:07

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.2

我正在处理一个应用程序,如果它还没有值,我需要用空值填充哈希值。 @pet []包含3个哈希值,每个哈希值应该有:name,:age和:pet_type_id。此变量的目的是使用它来填充视图中的select_tags,如下所示:

<%= text_field_tag "pet[][name]", @pet_storage[t].name %>&nbsp;
<%= text_field_tag "pet[][age]", @pet_storage[t].age %>&nbsp;
<%= select_tag("pet[][pet_type_id]", options_from_collection_for_select(PetType.all, "id", "name", @pet_storage[t].pet_type_id), :prompt => 'Select a pet type') %>

这将为我的表单提供默认数据。如果默认数据不存在,我需要它只是为空(这就是为什么我试图用包含名称,年龄和pet_type_id键的空值用空字符串值填充@pet_storage。

这是我在控制器中使用的代码:

unless defined?(@pet_storage)
@pet_storage = Array.new
RecordsHelper::ALLOWED_PETS.times { |t| @pet_storage[t] = {name:'', age:'', pet_type_id:''}}
end

但是,我收到此错误

undefined method `name' for {:name=>"", :age=>"", :pet_type_id=>""}:Hash
Extracted source (around line #15):

12:         <%= f2.label :age %>&nbsp;
13:         <%= f2.label :pet_type_id, 'Type of pet'%>
14:         </br>
15:         <%= text_field_tag "pet[][name]", @pet_storage[t].name %>&nbsp;
16:         <%= text_field_tag "pet[][age]", @pet_storage[t].age %>&nbsp;
17:         <%= select_tag("pet[][pet_type_id]", options_from_collection_for_select(PetType.all, "id", "name",     @pet_storage[t].pet_type_id), :prompt => 'Select a pet type') %>
18:     </div>

为什么我不能在哈希上保存这些值?有没有更好的方法来实现我想要做的事情?谢谢!

5 个答案:

答案 0 :(得分:0)

arr = []

3.times do |i|
  arr[i] = {a: 1, b: 2}
end

puts arr[2][:a]  #=>1

puts arr[2].a

1.rb:7:in `<main>': undefined method `a' for {:a=>1, :b=>2}:Hash (NoMethodError)

答案 1 :(得分:0)

这不是正确的方法。我希望你的意图是填充相应的对象值(如果存在),否则为空白。将pet_storage.try(:name)作为值传递。如果存在,这将获取值,否则返回nil,其中inturn显示为空白。同样,您可以为其他属性传递值:agepet_type_id

答案 2 :(得分:0)

您正在访问哈希,就像密钥是其上的方法一样,这是由此错误解释的

  

未定义的方法`name&#39; for {:name =&gt;&#34;&#34;,:age =&gt;&#34;&#34;,:pet_type_id =&gt;&#34;&#34;}:哈希

有几种方法可以解决这个问题。您可以尝试的一件事是使用Struct而不是哈希来初始化@pet_storage,但我认为这有点过分。最简单的方法是检查@pet_storage是否存在

<%= text_field_tag "pet[][name]", @pet_storage ? @pet_storage[t].name : '' %>&nbsp;

这样,您就不必在控制器中设置任何内容。

答案 3 :(得分:0)

“name”是@pet_storage [t]哈希的关键。所以你必须访问

@pet_storage[t][:name]

答案 4 :(得分:0)

代码味道。

在这里忘记哈希,否则你将无休止的黑客攻击。

设置默认值的正确方法是在控制器级别甚至模型级别设置实例变量值。

然后在View中,通常只是引用实例变量的属性/方法。

例如

# In controller
@pet.name = "Dog"

# In view
<%= form_for @pet %>
  <%= text_field_for :name %>

然后在浏览器中,文本字段将填充“Dog”。简单。