0

I have a concept called snapshot which basically stores a snapshot of how data looked at a certain period of time. What I'm building is a method that loops through the snapshots for each events, and builds a small hash outlining the ownership over time for a given shareholder.

  def fetch_ownership_over_time(shareholder, captable)

    @shareholder = Shareholder.find(shareholder.id)
    @captable = Captable.find(captable.id)
    @company = @captable.company.id
    @ownership_over_time = []

    @captable.events.collect(&:snapshot).each do |snapshot|
      parsed_snapshot = JSON.parse(snapshot)

      @ownership_over_time.push(parsed_snapshot["event"]["name"])
      @ownership_over_time.push(parsed_snapshot["event"]["date"])

      parsed_snapshot["shareholders"].each do |shareholder|
        if shareholder["id"] == @shareholder.id

          @ownership_over_time.push(shareholder["ownership_percentage"]) 

        end
      end
    end
    return @ownership_over_time
  end

I then call this method in my view which successfully retrieves the correct values however they are not structured in any way:

["Event 1 ", "2018-11-19", "0.666666666666667", "Event 2 ", "2018-11-19", "0.333333333333333", "4th event ", "2018-11-19", "0.315789473684211"]

What I'd like to do now though is construct my hash so that each separate snapshot event contains a name, date and ownership_percentage.

Perhaps something like this:

ownership_over_time = [
    {
    event_name = "Event 1" #parsed_snapshot["event"]["name"]
    event_date = "20180202" #parsed_snapshot["event"]["date"]
    ownership_percentage = 0.37 #shareholder["ownership_percentage"]
    },
    {
    event_name = "Event 2" #parsed_snapshot["event"]["name"]
    event_date = "20180501" #parsed_snapshot["event"]["date"]
    ownership_percentage = 0.60 #shareholder["ownership_percentage"]
    }
]

My challenge though is that the ["event"]["name"] an ["event"]["date"] attributes I need to fetch when looping over my snapshots i.e. the first loop (.each do |snapshot|) whereas I get my ownership_percentage when looping over shareholders - the second loop (.each do |shareholder|).

So my question is - how can I build this hash in "two" places so I can return the hash with the 3 attributes?

Appreciative of guidance/help - thank you!

1 Answer 1

1

You have to create a new hash for the object and append that hash to the array of objects you are creating.

  def fetch_ownership_over_time(shareholder, captable)

    @shareholder = Shareholder.find(shareholder.id)
    @captable = Captable.find(captable.id)
    @company = @captable.company.id
    @ownership_over_time = []

    @captable.events.collect(&:snapshot).each do |snapshot|
      parsed_snapshot = JSON.parse(snapshot)
      shareholder = parsed_snapshot['shareholders'].select { |s| s['id'] == @shareholder.id }.first

      local_snapshot = {
        'event_name' => parsed_snapshot['event']['name'],
        'event_date' => parsed_snapshot['event']['date'],
        'ownership_percentage' => shareholder.try(:[], "ownership_percentage") || 0
      }

      @ownership_over_time.push local_snapshot
    end
    return @ownership_over_time
  end

Notice that I changed your second loop to a select. As you currently have it, you risk on pushing two percentages if the id is found twice.

EDIT:

Added functionality to use a default value if no shareholder is found.

Sign up to request clarification or add additional context in comments.

7 Comments

Great solution! Thank you!
Glad it suits your needs, perhaps there is a more efficient way to solve it or a more stylish way to write it, but I'm sure you can take it from here.
For sure - I've been pondering how best to solve this but will push on from here and try refactor a little. Thank you again!
One thing I've run into is that we get a crash if the ownership_percentage is null or none exist. Do you think I should just wrap the entire local_snapshot in an unless not null so that we skip creating that snapshot if so?
Or you could give a default value for it when creating the local_snapshot. As it is a percentage, a persona having 0 is probably what you want when none is found: 'ownership_percentage' => shareholder['ownership_percentage'] || 0
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.