Interesting. So that makes sense; however, I’m a little troubled by the fact that, even someone like me who’s familiar with the idiom you describe, could not discern why from reading the code. I don’t believe there’s any refactoring that’s going to make it more intuitable but I think a short preceding comment is probably in order to alert the reader to the higher level implications of the code. Something like: “map nested hashes to flatter attribute accessors so callers don’t have to suffer with net suite’s nesting”, would probably be enough to alert the reader that the block has a very real purpose – usability for the caller of net sweet.

-d


From: Aaron Christy <notifications@github.com<mailto:notifications@github.com>>
Reply-To: forever-inc/netsweet <reply@reply.github.com<mailto:reply@reply.github.com>>
Date: Thursday, December 19, 2013 at 9:28 AM
To: forever-inc/netsweet <netsweet@noreply.github.com<mailto:netsweet@noreply.github.com>>
Cc: David Watson <dwatson@forever.com<mailto:dwatson@forever.com>>
Subject: Re: [netsweet] [#61296250] Convert from SOAP to REST (#4)


In lib/netsweet/customer.rb:

>
>  module Netsweet
>    class Customer
> -    extend Forwardable
> -    def_delegators :@rvp_customer, :access_role, :external_id,
> -                   :internal_id, :email, :delete
> +    extend Translator
> +
> +    attr_accessor :properties
> +
> +    translate :properties do
> +      {
> +        first_name:   :firstname,
> +        last_name:    :lastname,
> +        email:        :email,
> +        internal_id:  :id,
> +        external_id:  [:externalid,  ->(v) { v[:internalid] }, ->(v) { { internalid: v } }],


Great question. The short answer (and I'm not trying to be snarky here): because NetSuite is complicated and inconsistent.

The entire translate block is responsible for translating properties on the Netsweet::Customer object to and from the values expected by NetSuite which the REST gem wrapper returns as a ruby hash. It uses the Translator<https://github.com/forever-inc/netsweet/blob/rest-conversion/lib/netsweet/translator.rb> to do this work.

The job of the Translator is to create accessors for all of the properties defined in the block and be smart enough to know how to convert data to and from the NetSuite format. In the case above, all of the data is written to and from the @properties openstruct (as referenced on line 10).

The simplest translation is found as an example on line 12 where first_name becomes an accessor on Netsweet::Customer and simply proxies to the value of firstname on @properties<https://github.com/properties>. (So, basically it is doing the equivalent of@properties.firstname). Since this is a relatively common task (see lines 12-15), it made sense to have something that handled this logic rather than explicitly creating multiple methods to do it. If all we needed to do was a simple one-to-one mapping, we probably would have stuck with using the native Forwardable module like we were doing previously (see lines 7-9 above that were removed with this commit). Unfortunately, some of the other properties needing extraction didn't follow this pattern and ended up being more complicated.

Line 16 is an example of a more complicated translation. The goal here is to define an accessor called external_id that pulls the externalid value from @properties. Unfortunately, NetSuite returns externalid as a hash where the value we want is actually stored as internalid and it is buried in the hash. So, the first proc is pulling the actual value we want from this hash. Likewise, when we want to set external_id, we need it translated into the format that NetSuite understands. This is being done in the second proc.

The Translator<https://github.com/forever-inc/netsweet/blob/rest-conversion/lib/netsweet/translator.rb> module should provide further detail into this implementation.

Sorry for this long winded explanation, but hopefully it clears up any confusion.

—
Reply to this email directly or view it on GitHub<https://github.com/forever-inc/netsweet/pull/4/files#r8470146>.