views:

7

answers:

1

I am using Builder to construct XML messages being sent to a WebService. Each of the different methods require different xml but they all have a set of common elements to start of the request (mostly account authentication stuff). Is there any way to do it in a DRY way? Here is my code for constructing a change pass phrase request:

# XML REQUEST SETUP
msg = Builder::XmlMarkup.new(:indent=>2)
query = {}
test_hsh = self.testmode ? {:Test => "YES"} : {}

# BUILD THE REQUEST
query[:changePassPhraseRequestXML] = msg.ChangePassPhraseRequest(test_hsh) do |asr|
  asr.RequesterID APP_CONFIG[:endicia_partner_id].to_s
  asr.RequestID "1"
  asr.CertifiedIntermediary do |ci|
    ci.AccountID APP_CONFIG[:endicia_account_number].to_s
    ci.PassPhrase APP_CONFIG[:endicia_passphrase].to_s
  end
  asr.NewPassPhrase APP_CONFIG[:passphrase].to_s
end

Basically all the elements except the NewPassPhrase one are common to all (or most) requests. Right now I copy the same code over and over but I don't like this at all.

Any ideas on Dry'ing it up?

A: 

As soon as I posted this. I had an idea, put the first set into their own method. Duh!

def account_status(options = {})
  # XML REQUEST SETUP
  msg = Builder::XmlMarkup.new(:indent=>2)
  query = {}
  test_hsh = self.testmode ? {:Test => "YES"} : {}

  # BUILD THE REQUEST
  query[:changePassPhraseRequestXML] = msg.ChangePassPhraseRequest(test_hsh) do |asr|
    self.add_authentication_elements(asr)
    asr.NewPassPhrase APP_CONFIG[:new_pass_phrase].to_s
  end
end

def add_authentication_elements(parent_node)
  parent_node.RequesterID self.endicia_partner_id.to_s
  parent_node.RequestID "1"
  parent_node.CertifiedIntermediary do |ci|
    ci.AccountID self.endicia_account_number.to_s
    ci.PassPhrase self.endicia_passphrase.to_s
  end
end

Works great! Another option would of course be to extend Builder in some way but this is nice and simple.

ChrisH