Populating a table using JSON from the database in Rails - ruby-on-rails
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?
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 %>
Related
How to iterate each value which retrieve from DB and display them in UI?
How to iterate each value which retrieve from DB and display them in UI? Below the code I am trying Controller def execution_results executionId1=params['executionId1'] executionId2=params['executionId2'] execution_results1 = ExecutionResult.where(:execution_id => executionId1).pluck(:parametersname,:actual_value) execution_results2 = ExecutionResult.where(:execution_id => executionId2).pluck(:parametersname,:actual_value) puts execution_results1 puts execution_results2 end Now getting below response for execution_results1 and execution_results2 in Controller. 7.0ms) SELECT "execution_results"."parametersname", "execution_results"."actual_value" FROM "execution_results" WHERE "execution_results"."execution_id" = ? [["execution_id", 8]] (0.1ms) SELECT "execution_results"."parametersname", "execution_results"."actual_value" FROM "execution_results" WHERE "execution_results"."execution_id" = ? [["execution_id", 9]] Device.usage 12 Device.name A1 Device.number 12345 Device.usage 13 Device.name A1 Device.number 12346 Now requirement is to compare above result and show them in Ui as below.Can anyone please help how to bring like this? |S.No |Param Name |Value|Param Name |Value|Matched| | 1. Device.usage 12 Device.usage 13 No | 2. Device.name A1 Device.name A1 Yes
Assuming execution_results1 and execution_results2 have the same number of records, You can show the results in above-mentioned format by following lines in view <table> <tr> <th>Sr.no</th> <th>Param Name</th> <th>Value</th> <th>Param Name</th> <th>Value</th> <th>Matched</th> </tr> <% #execution_results.each do |result, index| %> <tr> <td><%= index + 1 %></td> <td><%= result.name %></td> <td><%= result.value %></td> <td><%= #execution_results2[index].name %></td> <td><%= #execution_results2[index].value %></td> <td><%= compare_function(result, #execution_results2[index]) %></td> </tr> <% end %> </table> compare_function here is a helper function which will be in your controller's helper and will look something like below (execution_results1.usage == execution_results2.usage) && (execution_results1.number == execution_results2.number) OR Whatever condition you want to compare Don't forget to change execution_results1, execution_results to #execution_results1, #execution_results2.to_a in your controller
Rails - Redirect to specific record page
I'm pretty new to Ruby on Rails and Ruby in general but I'm trying to make a small website with simple database in Ruby on Rails. At the moment I have the html.erb pages to show, add and edit records. The next thing i wanted to do is the action that redirects user to a page with more info about the record he clicked in the record table. I can't really think of any way to do this. Any help would be really appriciated. p.s. Sorry for any mistakes in my English - it's not my first language and im still learning! Here is my html code: <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="tablecontainer"> <table class="table table-bordered table-condensed"> <tr class="success"> <td><b>Nazwa</b></td> <td><b>Obrażenia</b></td> <td><b>Typ</b></td> <td><b>Waga</b></td> <td><b>Zasięg</b></td> <td><b>Szybkość</b></td> <td><b>Rzadkość</b></td> <td><b>Opcje</b></td> </tr> <% #biala.each do |b| %> <tr> <td><%= b.nazwa %></td> <td><%= b.obrazenia %>%</td> <td><%= b.typ %></td> <td><%= b.waga %></td> <td><%= b.zasieg %></td> <td><%= b.szybkosc %></td> <td><%= b.rzadkosc %></td> <td><%= link_to '', {id: b.id, action: 'db_wiecejbiala'}, class: "glyphicon glyphicon-info-sign" %><%= link_to '', {id: b.id, action: 'db_edytujbiala'}, class: "glyphicon glyphicon-pencil" %> <%= link_to '', {id: b.id, action: 'usunbiala'}, data: {confirm: 'Jesteś tego pewien?'}, class: "glyphicon glyphicon-remove" %></td> </tr> <% end %> </table> And here is the controller: class BazaController < ApplicationController def db_bronbiala #biala = BronBiala.all #iloscbiala = BronBiala.count end def db_dodajbiala #nowybiala = BronBiala.new end def utworzbiala #nowybiala = BronBiala.new(parametrybiala) if #nowybiala.save redirect_to(action: 'db_bronbiala') else render('db_dodajbiala') end end def parametrybiala params.require(:bron_biala).permit(:nazwa, :obrazenia, :typ, :waga, :zasieg, :szybkosc, :rzadkosc, :zalety, :wady, :ciekawostki, :opis) end def usunbiala usuwaniebiala = BronBiala.find(params[:id]).destroy #biala = BronBiala.all render('db_bronbiala') end def db_edytujbiala #biala = BronBiala.all #edytowanabiala = BronBiala.find(params[:id]) end def aktualizujbiala #biala = BronBiala.all #edytowanabiala = BronBiala.find(params[:id]) if #edytowanabiala.update_attributes(parametrybiala) redirect_to(action: 'db_bronbiala') else render('db_edytujbiala') end end def db_wiecejbiala #biala = BronBiala.all #bialawiecej = BronBiala.find(params[:id]) end end And the db_bialawiecej code: <div class="content"> <h2>Lista:</h2> <div class="tablecontainer"> <table class="table table-bordered table-condensed"> <tr class="success"> <td><b>Nazwa</b></td> <td><b>Obrażenia</b></td> <td><b>Typ</b></td> <td><b>Waga</b></td> <td><b>Zasięg</b></td> <td><b>Szybkość</b></td> <td><b>Rzadkość</b></td> </tr> <% #bialawiecej.id do |b| %> <tr> <td><%= b.nazwa %></td> <td><%= b.obrazenia %>%</td> <td><%= b.typ %></td> <td><%= b.waga %></td> <td><%= b.zasieg %></td> <td><%= b.szybkosc %></td> <td><%= b.rzadkosc %></td> </tr> <% end %> </div> </div>
On click send id of clicked item (GET). you will have link similar to : localhost:3000/desired_model/5 then in action do #desired_model = DesiredModel.find(params[:id]) redirect user to desired show page. Show data. Next time please provide some code :)
RoR: how make query to return the sum values for each group?
been teaching myself how to build a simple ruby/rails site. trying now to figure out the caveats for data manipulation. group is working, how do i "sum" all the columns? index.html.erb <table> <tr> <th>Site</th> <th><7days</th> <th>>7days</th> <th>>30days</th> <th>>90days</th> <th>>180days</th> <th>>365days</th> </tr> <tr> <% #gdcomets.each do |dcomet| %> <td><%= dcomet.site %></td> <td><%= #sum1 %></td> <td><%= #sum2 %></td> <td><%= #sum3 %></td> <td><%= #sum4 %></td> <td><%= #sum5 %></td> <td><%= #sum6 %></td> </tr> <% end %> </table> dcomets_controller class DcometsController < ApplicationController # GET /dcomets # GET /dcomets.json def index #dcomets = Dcomet.all #gdcomets = Dcomet.group(:site) #sum1 = #gdcomets.map(&:ls7day).sum #sum2 = #gdcomets.map(&:gt7day).sum #sum3 = #gdcomets.map(&:gt30day).sum #sum4 = #gdcomets.map(&:gt90day).sum #sum5 = #gdcomets.map(&:gt180day).sum #sum6 = #gdcomets.map(&:gt365day).sum respond_to do |format| format.html # index.html.erb format.json { render json: #gdcomets } end end end
#sum = #gdcomets.map(&:data).sum :data being the name of the column you want to sum.
You'll get better performance letting SQL do the donkey work of summing everything: Dcomet.group(:site).sum(:data) Where :data is the name of column you want to sum. That will return a hash with the keys being the site values, and the values the corresponding sum for that site
Add link to methods to array in controller
I have a index method in my rails 4 application controller that looks like: def index #products = Product.all #headers = #products.map(&:data).flat_map(&:keys).uniq #product_data = #products.map{ |product| product[ :data ].values } end So #product_data ends up with something like: [["Table", "$199.99", "blue"], ["Book", "$9.99", "green"]] In my view, I put all of this in a unordered list. But now I'd like to have a link_to an edit and delete page for each product. How can I include this in my array, so I can display a link for each product on the view page?
You could add product_id to the result of product[:data].values array. Then use that product_id as parameter to your product url_helpers. #product_data = products.map{ |product| product[ :data ].values.unshift(product.id) } This should give you something similar to: [[1, "Table", "$199.99", "blue"], [2, "Book", "$9.99", "green"]]
I see there is no use of #product_data there.Why can't You display the data in a table in your index.html.erb and you can loop through every product,so that the edit and delete links appear to every product.Assuming that you have name,price and color attributes for your product model,just do like this In your index.html.erb: <table border=1> <tr> <th>Product Name</th> <th>Product Price</th> <th>Product Color</th> <th></th> <th></th> </tr> <% #products.each do |p| %> <tr> <td><%=p.name %></td> <td><%=p.price %></td> <td><%=p.color %></td> <td><%=link_to 'Edit', :action => "edit", :id => p.id %></td> <td><%=link_to 'Delete', :action => "delete", :id => p.id, :confirm => "Are you sure?" %></td> </tr> <% end %> </table> Note: Its just an another approach.
Rails returns a weird string
could anyone tell me why does my rails application returns this piece of code when I do a select statement? #<Driver:0x22ef3f0> The select statement is: current_schedule_record = { 'driver_name' => Driver.where(['id = ?', id]).select('first_name').first } and the view is: <% #trucks.each do |truck| %> <% record = ScheduleController.schedule_record(truck.id) %> <tr> <td><%= truck.id %></td> <td><%= record['driver_name'] %></td> </tr> <% end %>
From the documentation Be careful because this also means you're initializing a model object with only the fields that you've selected. So using select still creates a model object. You need to use something like current_schedule_record = { 'driver_name' => Driver.where(['id = ?', id]).select('first_name').first.first_name }