我有一个厨师DataBag,我正在尝试阅读和使用厨师食谱,并踢它我的屁股。请注意:我不是程序员,使用Chef是我第一次进入Ruby。
根据我在网上找到的示例,这里是我的Chef服务器上data_bags文件夹下的数据库“AWSProd”的内容,它位于一个名为WEB的文件夹中:
{
"id" : "AWSProd",
"hosted_sites" : {
"siteA" : [
{
"site_name" : "siteA",
"site_doc_root_folder" : "siteA",
"site_simlink" : ""
}
],
"siteB" : [
{
"site_name" : "siteB",
"site_doc_root_folder" : "siteB",
"site_simlink" : ""
}
]
}
}
在我的食谱中,我正在使用以下内容来获取Databag:
WEB = data_bag("WEB")
WEB_env_globals = data_bag_item("WEB", node.chef_environment)
然后我基本上想迭代每个站点(siteA,siteB等)并获取site_name,site_doc_root_folder等的各个值......
我试图回应价值观,所以我知道它们有效。我试过这个:
WEB_env_globals["hosted_sites"].each do |site|
each_sitename = site["site_name"] ## can't convert String into Integer
each_site_doc_root_folder = site["site_doc_root_folder"]
each_site_simlink = site["site_simlink"]
execute "echo each site" do
command "echo #{each_sitename} #{each_site_doc_root_folder} #{each_site_simlink}"
action :run
end
end
但是我收到了一个“无法将String转换为整数”的错误,在我有双##的行上。
然后我尝试用这样的东西替换那一行:
each_sitename = WEB_env_globals["hosted_sites"][site]["site_name"]
然后我得到一个“未定义的方法`[]'为nil:NilClass”在该行上的错误。
我知道我在这里遗漏了一些完全基本的东西,而且我一直在寻找一个小时的清晰解释而且找不到一个。帮帮我Ruby-Won-Kenobi ......
答案 0 :(得分:1)
在您的数据包项目中,每个站点都是一个哈希数组。我不认为这是你的意图,因为你需要像以下一样访问它:
site[0]["site_name"]
你可能想要的是一个数据包项目,如:
{
"id" : "AWSProd",
"hosted_sites" : {
"siteA" : {
"site_name" : "siteA",
"site_doc_root_folder" : "siteA",
"site_simlink" : ""
},
"siteB" : {
"site_name" : "siteB",
"site_doc_root_folder" : "siteB",
"site_simlink" : ""
}
}
}
答案 1 :(得分:0)
好的,所以我明白了!对Hash Vs Arrays进行了一些教育......
以下是正确的红宝石块:
WEB_env_globals["hosted_sites"].each do |site,data|
data.each do |hash|
each_sitename = hash["site_name"]
each_site_doc_root_folder = hash["site_doc_root_folder"]
each_site_simlink = hash["site_simlink"]
execute "echo each site #{site}" do
command "echo #{each_sitename} #{each_site_doc_root_folder} #{each_site_simlink}"
action :run
end
end
end
答案 2 :(得分:0)
您在.each
上使用Hash
方法,但仅捕获密钥。
WEB_env_globals['hosted_sites'].each do |key, value|
- 但您只为其指定了密钥的名称。
each_sitename = site[....]
- 请记住该站点是键(String),因此您在[]
上调用String
方法,该方法需要一个Integer并返回该索引处的char。
* 您可以在任何ruby对象上调用.class
以找出它是什么类型。这对于疑难解答非常有帮助
因此,您可以更改数据库以使用哈希数组:
更改您的资料库:
{
"id" : "AWSProd",
"hosted_sites" : [
{
"site_name" : "siteA",
"site_doc_root_folder" : "siteA",
"site_simlink" : ""
},
{
"site_name" : "siteB",
"site_doc_root_folder" : "siteB",
"site_simlink" : ""
}
]
}
或者不管它并为你的代码尝试这个:(注意我也没有使用execute
块进行调试)
WEB_env_globals["hosted_sites"].each do |sitename, site_array|
site_array.each do |site|
each_sitename = site["site_name"]
each_site_doc_root_folder = site["site_doc_root_folder"]
each_site_simlink = site["site_simlink"]
Chef::Log.debug "#{each_sitename} #{each_site_doc_root_folder} #{each_site_simlink}"
# you could use puts or a higher level log message to make this easier to see in your output.
end
端