Sinatra: Array into HTML table - ruby

I am new to Sinatra.
I work currently on a project that is supposed to use a array,
for example: ary = ['a','b','c']
to covert it into an HTML table (possible using an .erb file).
The table should have a single column with as many rows, as there are strings (dynamic).
for example:
a
b
c
(any other item of the array)
I don't really have a clue how to do that and I tried code from similar projects, that didn't work. I hope its even possible to do.

In the controller do
get '/something' do
#ary = ['a','b','c']
erb :'something'
end
In the view named something you can do
<table>
<% #ary.each do |elem| %>
<tr>
<td>
<%= elem %>
</td>
</tr>
<% end %>
</table>

Related

How to iterate over rows and print out CSV::Table values in Sinatra

I'm making a simple Sinatra app and have the following 'numbers.csv' file:
Name,Title,Phone
Ally Smith,Manager,888-552-444
Rick Jones,Director,888-552-447
Hayley Bowman,Accountant,888-552-424
The task is to print the name and phone numbers in an erb file.
I originally solved this problem with nested arrays:
get '/' do
# turns CSV into array with nested arrays
#names = CSV.read('names.csv')
# delete headers
#names.shift
erb :index
end
and an each loop:
<tr>
<th>Name</th>
<th>Number</th>
</tr>
<% #names.each do |row| %>
<tr>
<td> <%= row[0] %> </td>
<td> <%= row[2] %> </td>
<tr>
<% end %>
Now I am trying to overcome my fear of working with objects and hashes, so I am approaching the problem like this:
get '/' do
# turns CSV into object with key value pairs
#numbers = CSV.read('numbers.csv', headers:true)
erb :index
end
I know that the benefit of using a CSV::Table object with headers means that I can access the values like so:
#names[i]["Name"]
#names[i]["Phone"]
where i is the counter for each row, followed by the key names.
I tried writing a while loop in the erb file – fail. Also a foreach loop that I understand is as CSV method and modified my code accordingly – fail.
I'm having trouble iterating over the rows and calling the specific keys.
I'm not sure if I am using the right loops.
Any advice would be greatly appreciated.
I have been working on this for hours :(
The code is fine. As i show below:
> numbers = CSV.read('numbers.csv', headers:true)
> numbers.each do |row|
> puts "#{row['Name']} - #{row['Phone']}"
> end
Ally Smith - 888-552-444
Rick Jones - 888-552-447
Hayley Bowman - 888-552-424
I think your problem is your variables. you should use #numbers instead of #names in your second example:
#names[i]["Name"] # should be #numbers[i]['Name']

The proper search result is not coming using Rails 3

I need to access all values from Database according to id but i am getting the following output.
Output:
all details are #<PaymentVendor:0x1ee5860>
all details are #<PaymentVendor:0x1f02798>
I am explaining my code below.
#rest_ids=[21,22,23]
#rest_ids.each do |ids|
#pdf_vendor_details = PaymentVendor.where(:id => ids )
puts "all details are #{#pdf_vendor_details}"
end
From the above code i have some array of ids(i.e- #rest_ids).Here my requirement is when the loop will execute as per id the record will fetch and store in the variable #pdf_vendor_details in array.If I wanted to display some value in table then i will be able to do that like below.
table.html.erb:
<table>
<tr>
<td>ID</td>
<td>Receipt No</td>
<td>Amount</td>
</tr>
<% #pdf_vendor_details.each do |details| %>
<tr>
<td><%= details.id %></td>
<td><%= details.Receipt_No %></td>
<td><%= details.Amount %></td>
</tr>
<% end %>
</table>
But doing this way i can not get any value and unable to display data in table.Please help me to access the data from DB which will store in array to display in table.
Try this:
#pdf_vendor_details = PaymentVendor.where(:id => #rest_ids ) #rails 4
#OR
#pdf_vendor_details = PaymentVendor.find_all_by_id(#rest_ids) #rails 3
#pdf_vendor_details.each do |pdf|
puts "all details are: ID => #{pdf.id}, Receipt_No => #{pdf.Receipt_No}, Amount=> #{pdf.Amount}"
end
Your table.html.erb will be not changed
You can try
PaymentVendor.where(id: [21, 22, 23])
which will build a SQL statement like
SELECT * FROM payment_vendors WHERE id IN (21, 22, 23)
I don't see any reason in looping #rest_ids and querying on each iteration
#pdf_vendor_details = PaymentVendor.where(:id => ids )
and in each iteration you are replacing the previous value of #pdf_vendor_details instead of appending to the array.
Instead
#pdf_vendor_details = PaymentVendor.where(id: #rest_ids ) #rails 4
or
#pdf_vendor_details = PaymentVendor.find_all_by_id(#rest_ids) #rails 3
will do. It will send one query to fetch all records of paymentvendor in those ids'.
Update:
If you want to print the contents of the object #pdf_vendor_details in raw form, you could use .inspect or .to_yaml.
For example, puts #pdf_vendor_details.inspect, will print the contents of the object.
Refer this question, to print contents of object.
#rest_ids=[21,22,23]
#pdf_vendor_details = PaymentVendor.where(id: #rest_ids )
puts "All details are, #{#pdf_vendor_details.inspect}"

Divide loop iteration in an html.erb file over different sections for enhancing performance

This is part of my code in an html.erb file
<div class="list_carousel">
<ul id="products-carousel" class="carousel">
<% #posts.select{ |post| post.categories.include?(#categories.find_by_name("Productos")) }.each do |post|%>
[...]
<% end %>
</ul>
</div>
[...]
<div class="modals">
<% #posts.select{ |post| post.categories.include?(#categories.find_by_name("Productos")) }.each do |post|%>
[...]
<% end %>
</div>
The problem here is that I'm using several database queries to perform this loop and I would like to re-use the first loop in other parts of this files in order to enhance performance.
For example I would like to do something like each do |post| do something in this first section, don't do nothing in this second section and continue in the third one. This way I could re-use the instance of the selected postd over which I'm iterating.
In your controller, you can do this:
#posts = Post.all
#productos_category = #categories.where(name: "Productos").first
#productos = #posts.where(category_id: #productos_category.id)
Note that I changed the way you find the associated #productos to use the ActiveRecord query interface, as opposed to using pure ruby select and include? methods. This will allow for the query to be much more efficient. I implied some things, such as the child key for the categories being category_id. Change this where appropriate.
EDIT 1
I believe this will work, although my experience with many-to-many relationships is somewhat limited:
#productos_category = #categories.where(name: "Productos").first
#productos_posts = Post.joins(:join_table).where(join_table: {category_id: #productos_category.id})
Where :join_table is the name of the table that is used in the has_many association. If it is a HABTM relationship, this will probably be called categories_posts.
Then your view would change to this:
<div class="list_carousel">
<ul id="products-carousel" class="carousel">
<% #productos_posts.each do |post|%>
[...]
<% end %>
</ul>
</div>
[...]
<div class="modals">
<% #productos_posts.each do |post|%>
[...]
<% end %>
</div>

instance variable inside edit method for webform (Rails)

Rails (version 4) question: I have a table called "sections" and I generate a controller called Sections like this:
rails generate controller Sections index show edit new delete
When I browse to, for example, http://localhost:3000/sections/edit/4 I don't see the prepopulated values (the values from the DB which I wish to edit) in the webform.
I need to add some details. The edit and update methods (found in sections_controller.rb) are created as:
def edit
#sect = Section.find(params[:id])
end
def update
#sect = Section.find(params[:id])
if #sect.update_attributes(sect_params)
redirect_to(:action=>'index')
else
render('edit')
end
end
The update method doesn't require a template file, but edit does. So in the view\sections\edit.html.erb we have:
<%= form_for(:section, :url => {:action => 'update', :id => #section.id}) do |f| %>
<table>
<tr>
<th> Field 1 </th>
<td> <%= f.text_field(:field1) %> </td>
</tr>
<tr>
<th> Field 2 </th>
<td> <%= f.text_field(:field2) %> </td>
</tr>
</table>
<%= submit_tag("Edit section") %>
<% end %>
So the edit mechanism works perfectly, except that I don't see the prepopulated fields in the edit webform (which is inconvenient to say the least, especially in case of a large number of fields).
I already corrected this by renaming the #sect (only from method edit) instance variable to #section. However, I am puzzled and astounded by this solution. Shouldn't I supposedly be allowed to choose any variable name? Is this a Rails bug? Please enlighten me.
(In every other language I was free to choose any variable name as pleased without any repercussions.)
Take a look at the docs for form_for. You aren't giving it the model object it should be creating the form with, you're just basically specifying the object's name with the :section symbol.
Instead, pass the object you want to edit in (form_for(#section...)), that should get you the pre-populated fields you are looking for.

HAML Ruby - conditionals

I'm going through examples from 'Agile Web Dev with Rails' book, but mixing it with extra techniques i found useful - like haml.
Got one tricky issue, how to write down this erb partial:
<% if line_item == #current_item %>
<tr id="current_item">
<% else %>
<tr>
<% end %>
<td><%= line_item.quantity %>×</td>
<td><%= line_item.product.title %></td>
<td class="item_price"><%= number_to_currency(line_item.total_price) %></td>
</tr>
In haml?
Tried sth like this:
-if line_item==#current_item
%tr#current_item
-else
%tr
%td!=line_item.quantity.to_s+"×"
%td=line_item.product.title
%td.item_price=number_to_currency(line_item.total_price)
But it prints out an empty TR without TD within...
Rather than having two separate %tr entries (in which case you would need to list your 3 td's under each tr, I think), you could just set the id in a conditional:
%tr{:id => (line_item == #current_item) ? "current_item" : false}
%td!=line_item.quantity.to_s+"×"
%td=line_item.product.title
%td.item_price=number_to_currency(line_item.total_price)

Resources