嵌入式Ruby:Array.each“无方法”错误

时间:2015-11-26 06:09:42

标签: javascript ruby-on-rails arrays ruby

在我的助手中,我从数据库中生成哈希。哈希包含每个州的一个键,其值包含一系列城市。每个城市条目本身都是一个数组,名称和ID。

例如(此代码只是一个例子):

myHash[key => MD, value=>[ ['Annapolis',1],['Potomac',2] ] ]

这是产生哈希的实际代码:

def get_city_hash
  stateHash = Hash.new
  City.all.each do |c|
    if !stateHash.include? c.stateab
      stateHash[c.stateab] = Array.new
    end
    stateHash[c.stateab] << [c.name, c.id]
  end
end

问题是当我尝试在javascript中创建一个相关的关联数组时,似乎我的每个城市的Array对象都没有.each方法(在中间取出代码以减少混乱)

  var city_array = [
  <% get_city_hash.each do |key, value|%>
    <%value.each do |v|%>
    <%end%>
 <%end%>

对于此代码,我在包含value.each:

的行上收到此错误
  

未定义的方法`each'代表nil:NilClass

我在帮助器中对状态数组测试了一个.each,它工作正常。这种格式有什么变化,我得到了一个N​​ilClass?

4 个答案:

答案 0 :(得分:0)

我认为,你定义了一个名为&#34; get_city_hash&#34;的辅助方法。并且您在视图中调用&#34; get_city_array&#34;。改变&#34; get_city_array&#34;到&#34; get_city_hash&#34;

答案 1 :(得分:0)

您可以尝试:

 <% get_city_hash.each do |key, value|%>
    <% unless value.blank? %>
     <%value.each do |v|%>

     <%end%>
    <% end%>
 <%end%>

或者您可以尝试使用nil value

从哈希compact中删除get_city_hash.compact.each

导轨4.1 compact读取:http://api.rubyonrails.org/classes/Hash.html#method-i-compact

     <% get_city_hash.compact.each do |key, value|%>
     <%value.each do |v|%>

     <%end%>
   <%end%>

答案 2 :(得分:0)

这教会我们依靠Ruby超级简洁的配方......

我的帮助方法是返回一些索引值,而不是我正在制作的实际哈希值!

答案 3 :(得分:0)

你有两个问题。

问题#1

您的get_city_hash方法未返回cityHash,它会返回each的结果,这将是您调用它的枚举(即City.all的结果)。这不是哈希,所以当你在它上面调用each时,只有一个参数被传递到块中,而第二个参数c总是nil

最重要的是,该方法还有很大的改进空间。首先,代替if !stateHash.include?业务,只需为您的Hash提供默认值:

def get_city_hash
  state_hash = Hash.new {|h,k| h[k] = [] }

  City.select(:id, :stateab, :name).all.each do |c|
    state_hash[c.stateab] << [c.name, c.id]
  end

  state_hash
end

我还添加了select,因为您永远不应该从数据库中检索您不会使用的列。

但我们可以使用each_with_object

进行更多清理
def get_city_hash
  city_hash = Hash.new {|h,k| h[k] = [] }

  City.select(:id, :stateab, :name).all
    .each_with_object(Hash.new([])) do |city, city_hash|
      city_hash[city.stateab] << city.values_at(:name, :id)
    end
end

或者我们可以做到这一点,这可能有点过于“聪明”,但我仍然非常偏爱。

def get_city_hash
  City.all.pluck(:stateab, :name, :id)
    .group_by(&:shift)
end

问题#2

在您看来,您正在尝试生成JavaScript代码,这绝不是一个好主意。你应该总是让Rails为你生成有效的JSON:

 
var cities = <%= raw get_city_hash.to_json %>;