Search code examples
jsonrubychef-infraerbchef-recipe

How to handle optional methods/attributes of json in Chef


I have a Chef erb file where I am printing values from json. The json has some optional attributes, like following. Please note that last object of json doesnt have "role" attribute.

"users": [
  {"name" : "ccsup", "desc" :"abc", "role":"CS" },
  {"name" : "support", "desc" :"xyz", "role":"Operation" },
  {"name" : "admin", "desc" :"admin" }
]

I am reading this json in an ERB file and generating a template like following

<% users = @users_json -%>
<?xml version="1.0" encoding="UTF-8"?>
<users>
    <% users.each do |user| -%>
    <user lockCount="0" name="<%= user.name -%>" desc="<%= user.desc -%>" status="A">
        <% if user.role -%>
        <role><%= user.role -%></role>
        <% end -%>
    </user>
    <% end -%>
</users>

if I add "role" attribute to all objects in json then code works. But I will have some users where "role" will not be there. And for those I want to skip xml tag.

If I dont have "role" attribute to some objects, I am getting

Chef::Mixin::Template::TemplateError (Undefined method or attribute `role' on `node') on line #6

Solution

  • The .foo syntax for attributes has been removed in newer Chef, so we don't recommend you use it all. Instead do <%= user["name"] %> and then for something that needs a default <%= user["role"] || "defaultvalue" %>.