Creating Message Object Parser

53 views Asked by At

I'm receiving results from a web service like this:

result.body returns:

[2] pry(#<User::EmailSettingsController>)> result.body
=> {"RESULT"=>
  {"MESSAGES"=>
    [{"MESSAGE"=>
       {"TYPE"=>"E",
        "ID"=>"HRRCF_WD_UI",
        "NUMBER"=>"025",
        "MESSAGE"=>"U kunt maximaal \"5\" jobagents creëren 1",
        "LOG_NO"=>"",
        "LOG_MSG_NO"=>"000000",
        "MESSAGE_V1"=>"5",
        "MESSAGE_V2"=>"1",
        "MESSAGE_V3"=>"",
        "MESSAGE_V4"=>"",
        "PARAMETER"=>"",
        "ROW"=>"0",
        "FIELD"=>"",
        "SYSTEM"=>""}},
     {"MESSAGE"=>
       {"TYPE"=>"E",
        "ID"=>"HRRCF_WD_UI",
        "NUMBER"=>"025",
        "MESSAGE"=>"U kunt maximaal \"5\" jobagents creëren 2",
        "LOG_NO"=>"",
        "LOG_MSG_NO"=>"000000",
        "MESSAGE_V1"=>"5",
        "MESSAGE_V2"=>"2",
        "MESSAGE_V3"=>"",
        "MESSAGE_V4"=>"",
        "PARAMETER"=>"",
        "ROW"=>"0",
        "FIELD"=>"",
        "SYSTEM"=>""}},
     {"MESSAGE"=>
       {"TYPE"=>"E",
        "ID"=>"HRRCF_WD_UI",
        "NUMBER"=>"025",
        "MESSAGE"=>"U kunt maximaal \"5\" jobagents creëren 3",
        "LOG_NO"=>"",
        "LOG_MSG_NO"=>"000000",
        "MESSAGE_V1"=>"5",
        "MESSAGE_V2"=>"3",
        "MESSAGE_V3"=>"",
        "MESSAGE_V4"=>"",
        "PARAMETER"=>"",
        "ROW"=>"0",
        "FIELD"=>"",
        "SYSTEM"=>""}}]}}

Is it possible to create something ParseMessageObject(result.body) that returns that I can do something like this.

message_list = ParseMessageObject(result.body)
message_list.each do |message|
 puts message.message
 puts message.type
end

I have no idea if this is possible or how to do this any suggestions to get me started are welcome!

EDIT 1: Created my class in lib:

class MessageParser
    def self.parse(result)

    end 
end
2

There are 2 answers

0
Andy Henson On BEST ANSWER

This should basically do what you want, using a simple open struct to create a message class which has accessors for each of the keys in your message hash

require 'ostruct'

class MessageParser
  Message = Struct.new(:type, :id, :number, :message, :log_no, :log_msg_no, :message_v1, :message_v2, :message_v3, :message_v4, :parameter, :row, :field, :system)

  attr_reader :messages
  def initialize(data)
    @data = data.fetch("MESSAGES",[])
    @messages = []
    parse_data
  end

  private
  def parse_data
    @data.each do | msg |
      message = Message.new
      msg.fetch("MESSAGE",{}).each do |key, value|
        message[key.downcase.to_sym] = value
      end
      @messages << message
    end
  end
end

parser = MessageParser.new(result.body["RESULT"])
parser.messages.each do |message|
  puts message.message
  puts message.type
end
0
zwippie On

Something like this should work:

class ParsedMessages
  include Enumerable
  attr_reader :messages

  def initialize(data)
    @messages = extract_messages_from_data(data)
  end

  def extract_messages_from_data(data)
    # TODO: Parse data and return message objects
  end

  def each &block  
    @messages.each do |message|
      if block_given?
        block.call message
      else  
        yield message
      end
    end  
  end

end

Now you can use all methods from Enumerable on ParsedMessages, like each, find, map etc etc.