mf370
mf370

Reputation: 331

Array of Hashes to JSON File Ruby

I'm trying to create JSON files dynamically, where the content of each file belongs only to a certain entity.

I have an array of Ruby objects, where each object represents an entity.

entities = [#<Entity:0x0055f364d9cd78 @name="entity-B", @internal_asn_number=64514, @classification_id="B">,#<Entity:0x0055f364d89070 @name="entity-A", @internal_asn_number=64513, @classification_id="A">] 

And I have an array of hashes, which contains several rules for each entity and I would like to write these hashes to JSON files, one file per entity.

I have the following code:

array_hashes = [{"rulename"=>"entity-B_source_fqdn_1", "if"=>{"source.fqdn"=>"mail.tec.dsr.entityB.com"}, "then"=>{"event_description.text"=>"B"}}, {"rulename"=>"entity-B_destination_fqdn_1", "if"=>{"destination.fqdn"=>"mail.tec.dsr.entity_B.com"}, "then"=>{"event_description.text"=>"B"}}, {"rulename"=>"entity-A_source_fqdn_1", "if"=>{"source.fqdn"=>"194-65-57-128.entityA.com"}, "then"=>{"event_description.text"=>"A"}}, {"rulename"=>"entity-A_destination_fqdn_1", "if"=>{"destination.fqdn"=>"194-65-57-128.entityA.com"}, "then"=>{"event_description.text"=>"A"}}]

path = "/home/mf370/Desktop/RubyProject/"
file_name = "_url_fqdn.conf"

 entities.each do |entity|
    File.open(path + entity.name + file_name, "w") do |f|
      array_hashes.each do |rule|
          if rule['rulename'].match(entity.name)
            f.write(JSON.pretty_generate([rule]))
          end
      end
    end

This code works and creates the files dynamically, however the content of the files is not what I was expecting.

This is the output from the code above:

[
  {
    "rulename": "entity-A_source_fqdn_1",
    "if": {
      "source.fqdn": "194-65-57-128.entityA.com"
    },
    "then": {
      "event_description.text": "A"
    }
  }
][
  {
    "rulename": "entity-A_destination_fqdn_1",
    "if": {
      "destination.fqdn": "194-65-57-128.entityA.com"
    },
    "then": {
      "event_description.text": "A"
    }
  }
]

And this is the output that I was looking for:

[
  {
    "rulename": "entity-A_source_fqdn_1",
    "if": {
      "source.fqdn": "194-65-57-128.entityA.com"
    },
    "then": {
      "event_description.text": "A"
    }
  },
  {
    "rulename": "entity-A_destination_fqdn_1",
    "if": {
      "destination.fqdn": "194-65-57-128.entityA.com"
    },
    "then": {
      "event_description.text": "A"
    }
  }
]

Probably this is very simple to solve, but I ran out of ideas on how to solve this, I'm new to Ruby Programming. Thank you for your help!

Upvotes: 1

Views: 2284

Answers (2)

Daniel Christiany
Daniel Christiany

Reputation: 227

The Problem is that you wrap each rule in an array. THis should solve the issue:

json_entities = []
entities.each do |entity|
    File.open(path + entity.name + file_name, "w") do |f|
        array_hashes.each do |rule|
            if rule['rulename'].match(entity.name)
                json_entities << rule
            end
        end
    end
end
f.write(JSON.pretty_generate(json_entities))

Upvotes: -1

Eric Duminil
Eric Duminil

Reputation: 54223

The problem is that you pack each rule inside an array :

JSON.pretty_generate([rule])

You should create an array of matching rules, and dump it as JSON :

entities.each do |entity|
  File.open(File.join(path, entity.name + file_name), "w") do |f|
    matching_rules = array_hashes.select{ |rule| rule['rulename'].match(entity.name) }
    f.write(JSON.pretty_generate(matching_rules))
  end
end

Upvotes: 2

Related Questions