0

I have the following JSON stored in my database under an column called event (using the json column type).

{
   "captable":{
      "id":28,
      "version":1,
      "name":"CapTable",
      "company_id":22,
      "created_at":"2018-10-31T18:56:03.965Z",
      "updated_at":"2018-10-31T18:57:30.626Z",
      "total_stocks_in_company":"400.0"
   },
   "event":{
      "status_locked":null,
      "id":51,
      "price_per_share":"1000.0",
      "total_company_stocks_after_event":"400.0",
      "name":"2nd event ",
      "date":"2018-10-31",
      "currency":"SEK",
      "valuation":"400000.0",
      "created_at":"2018-10-31T18:57:17.282Z",
      "updated_at":"2018-10-31T18:57:30.676Z",
      "captable_id":28,
      "company_id":22,
      "snapshot":"{\"captable\":{\"id\":28,\"total_stocks_in_company\":\"400.0\",\"version\":1,\"name\":\"CapTable\",\"company_id\":22,\"created_at\":\"2018-10-31T18:56:03.965Z\",\"updated_at\":\"2018-10-31T18:57:30.626Z\"},\"event\":{\"status_locked\":null,\"id\":51,\"price_per_share\":\"1000.0\",\"total_company_stocks_after_event\":\"400.0\",\"name\":\"2nd event \",\"date\":\"2018-10-31\",\"currency\":\"SEK\",\"valuation\":\"400000.0\",\"created_at\":\"2018-10-31T18:57:17.282Z\",\"updated_at\":\"2018-10-31T18:57:30.665Z\",\"captable_id\":28,\"company_id\":22,\"snapshot\":null},\"shareholders\":[{\"id\":52,\"shareholder\":\"Peter\",\"name\":\"Peter\",\"number_of_stocks\":\"100.0\",\"company_id\":22,\"created_at\":\"2018-10-31T18:55:42.730Z\",\"updated_at\":\"2018-10-31T18:57:30.637Z\",\"ownership_percentage\":\"0.25\",\"email\":\"\",\"telephone\":\"\"},{\"id\":53,\"shareholder\":\"Jane\",\"name\":\"Jane\",\"number_of_stocks\":\"100.0\",\"company_id\":22,\"created_at\":\"2018-10-31T18:55:49.490Z\",\"updated_at\":\"2018-10-31T18:57:30.644Z\",\"ownership_percentage\":\"0.25\",\"email\":\"\",\"telephone\":\"\"},{\"id\":54,\"shareholder\":\"Sally\",\"name\":\"Sally \",\"number_of_stocks\":\"200.0\",\"company_id\":22,\"created_at\":\"2018-10-31T18:55:56.192Z\",\"updated_at\":\"2018-10-31T18:57:30.651Z\",\"ownership_percentage\":\"0.5\",\"email\":\"\",\"telephone\":\"\"}]}"
   },
   "shareholders":[
      {
         "id":52,
         "shareholder":"Peter",
         "name":"Peter",
         "number_of_stocks":"50.0",
         "company_id":22,
         "created_at":"2018-10-31T18:55:42.730Z",
         "updated_at":"2018-10-31T18:58:31.406Z",
         "ownership_percentage":"0.125",
         "email":"",
         "telephone":""
      },
      {
         "id":53,
         "shareholder":"Jane",
         "name":"Jane",
         "number_of_stocks":"150.0",
         "company_id":22,
         "created_at":"2018-10-31T18:55:49.490Z",
         "updated_at":"2018-10-31T18:58:31.410Z",
         "ownership_percentage":"0.375",
         "email":"",
         "telephone":""
      },
      {
         "id":54,
         "shareholder":"Sally",
         "name":"Sally ",
         "number_of_stocks":"200.0",
         "company_id":22,
         "created_at":"2018-10-31T18:55:56.192Z",
         "updated_at":"2018-10-31T18:57:30.651Z",
         "ownership_percentage":"0.5",
         "email":"",
         "telephone":""
      }
   ]
}

I can successfully render the JSON to my view using

<%= @event.snapshot %> 

However, what I'd like to do now is fill a table in my view using the json column as the data source, but I'm having trouble figuring out where to put the logic, whether ot have it in the view of have a separate method in either the controller or model.

What I'd love to do is have a table that looks like this: (pseudocode)

<table class="table">
  <tr>
    <th>Shareholder</th>
    <th>Name</th>
    <th>Number of Shares</th>
    <th>Ownership %</th>
  </tr>

<%= @event.snapshot["shareholders"].each do |shareholder| %> 
  <tr>
    <td><%= shareholder.shareholder %></td>
    <td><%= shareholder.name %></td> 
    <td><%= shareholder.number_of_stocks %></td> 
    <td><%= shareholder.ownership_percentage %></td>
  </tr>
<%= end %> 
</table>

Can someone help point me in the right direction when it comes to filling a table using a json object instead of simply values from the database?

To clarify: how should I best access the shareholders when iterating through the JSON (i.e. <%= @event.snapshot["shareholders"].each do |shareholder| %> ) in order to create a new table row for each of them?

1 Answer 1

2

If you have a Shareholder model with the necessary attributes you can use the JSON to populate objects and then do pretty much what you did above. Note: the first line of the loop now creates a new object for each shareholder entry.

You'll need to parse the JSON first.

<% snapshot_json = JSON.parse(@event.snapshot) %>
<% snapshot_json["shareholders"].each do |shareholder_hash| %> 
  <% shareholder = Shareholder.new(shareholder_hash) %>
  <tr>
    <td><%= shareholder.shareholder %></td>
    <td><%= shareholder.name %></td> 
    <td><%= shareholder.number_of_stocks %></td> 
    <td><%= shareholder.ownership_percentage %></td>
  </tr>
<%= end %> 

If you don't want to create a new class/model you can just use the hash form of the JSON directly ...

<% snapshot_json = JSON.parse(@event.snapshot) %>
<% snapshot_json["shareholders"].each do |shareholder| %> 
  <tr>
    <td><%= shareholder["shareholder"] %></td>
    <td><%= shareholder["name"] %></td> 
    <td><%= shareholder["number_of_stocks"] %></td> 
    <td><%= shareholder["ownership_percentage"] %></td>
  </tr>
<%= end %> 
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! I'm getting the following error when using the hash form of the JSON directly (your second suggestion). undefined method 'each' for "shareholders":String
So obvious in retrospect. I thought because it was JSON in the database we wouldn't need to parse it. Thank you!
The only thing now is that renders the json out in the view above the table, but I'll figure out a way to not to do that. Perhaps I could move some of the functionality to a controller?

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.