Ruby访问嵌套哈希和erb模板

时间:2017-05-22 02:27:23

标签: ruby hash erb

我有以下哈希,列出了什么样的机器类型和Chef代码块上存在的服务。某些服务具有与之关联的端口号。

services_hash = {
  "bugs_services" => ["bugs"],
  "max_api_services" => ["max-api"],
  "max_api_ports_max-api" => 84,
  "max_data_services" => ["max-data-http"],
  "max_data_ports_max-data-http" => 85,
  "max_logger_services" => ["max-analytics", "max-logger"],
  "max_logger_ports_max-analytics" => 83,
  "max_logger_ports_max-logger" => 82
}

%w( max_api max_data max_logger ).each do |haproxy_chef_role|
  template "/home/ubuntu/ansible/deploy/role_#{haproxy_chef_role}.yml" do
    source 'haproxy_services.yml.erb'
    owner 'ubuntu'
    group 'ubuntu'
    action :create
    mode 0644
    variables({
      number_of_services: number_of_services,
      services: services_hash["#{haproxy_chef_role}_services"],
      ports: ???
      haproxy_chef_role: haproxy_chef_role
    })
  end
end

我还有一个类似于此的erb模板。

  <% @services.each do |service| -%>
    <% if service.include?("max-logger") %>
        shell: for i in {0..<%= @number_of_services %>}; do echo <%= service %>:<%= ports %>$(printf '%02d' $i); done
     <% else %>
        shell: echo <%= service %>:<%= ports %>00
     <% end %>
  <% end %>

如何嵌套哈希,以便端口号与给定服务相关联,我可以从erb模板中调用?

我在想这样的事情,我有一个数组,其中包含表示服务的字符串,然后是一个到端口的哈希映射服务。我认为这会有效,但我不知道如何正确提取数据以填写我的erb模板。

services_hash = {
  "max_logger_services" => [
    "max-logger",
    "max-analytics",
    { "max-analytics" => 83, "max-logger" => 82] }
}

我之前尝试过这样的事情,我将我正在处理的任何内容插入到另一个哈希查询中,但是它运行不正常并且似乎是错误的方法。

  ports: services_hash["#{haproxy_chef_role}_ports_#{services_hash["#{haproxy_chef_role}_services"]}"],

编辑:

我现在得到的行返回下面每个塞巴斯蒂安的答案的哈希值,该答案返回与端口相关的哈希值。

ports: services_hash['max_logger_services'].inject{|_k,v| v},

现在在erb模板中,我不太明白我应该如何查询哈希键的值。特别是我似乎无法在erb中将变量嵌套在一起。

  <% @services.each do |service| -%>
      <% if service.include?("max-logger") %>
        shell: for i in {0..<%= @number_of_services %>}; do echo disable server <%= service.gsub('max-', '') %>-backend/{{ ansible_fqdn   }}:<%= @ports["<%= service %>"] %>$(printf '%02d' $i) | sudo socat stdio /run/admin.sock; done
✗     <% else %>
        shell: echo disable server <%= service.gsub('max-', '') %>-backend/{{ ansible_fqdn }}:<%= @ports['<%= service -%>'] -%>00 | sud  o socat stdio /run/admin.sock
      <% end %>
  <% end %>

这一行似乎是问题所在。散列被传递给erb,但是我无法将正在处理的当前服务放入散列中来吐出一个值。这是我遇到的同样的根本问题,促使我提出这个问题:我似乎无法告诉我目前正在处理哪些服务来查找有关该特定服务的更多数据。

<%= @ports["<%= service %>"] %>

1 个答案:

答案 0 :(得分:2)

如果services_hash具有以下格式:

services_hash = {
  "max_logger_services" => [
    "max-logger",
    "max-analytics", { 
      "max-analytics" => 83, 
      "max-logger" => 82
    }
  ]
}

然后您可以访问max-analyticsmax-logger,只需:

hash = services_hash['max_logger_services'][2]
p hash['max-analytics']
# => 83
p hash['max-logger']
# => 82

如果你不知道数据是否总是以相同的方式格式化,至少你可以“挖掘”直到更深的哈希值:

hash = services_hash['max_logger_services'].inject{|_k,v| v}
# => {"max-analytics"=>83, "max-logger"=>82}