instance variable inside edit method for webform (Rails) - ruby

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.

Related

Linking to search results with Ruby

I'm a complete novice in Ruby and Nanoc, but a project has been put in my lap. Basically, the code for the page brings back individual URLs for each item linking them to the manual. I'm trying to create a URL that will list all of the manuals in one search. Any help is appreciated.
Here's the code:
<div>
<%
manuals = #items.find_all('/manuals/autos/*')
.select {|item| item[:tag] == 'suv' }
.sort_by {|item| item[:search] }
manuals.each_slice((manuals.size / 4.0).ceil).each do |manuals_column|
%>
<div>
<% manual_column.each do |manual| %>
<div>
<a href="<%= app_url "/SearchManual/\"#{manual[:search]}\"" %>">
<%= manual[:search] %>
</a>
</div>
<% end %>
</div>
<% end %>
</div>
As you didn't specify what items is returning, I did an general example:
require 'uri'
# let suppose that your items query has the follow output
manuals = ["Chevy", "GMC", "BMW"]
# build the url base
url = "www.mycars.com/search/?list_of_cars="
# build the parameter that will be passed by the url
manuals.each do |car|
url += car + ","
end
# remove the last added comma
url.slice!(-1)
your_new_url = URI::encode(url)
# www.mycars.com/?list_of_cars=Chevy,GMC,BMW
# In your controller, you will be able to get the parameter with
# URI::decode(params[:list_of_cars]) and it will be a string:
# "Chevy,GMC,BMW".split(',') method to get each value.
Some considerations:
I don't know if you are gonna use this on view or controller, if will be in view, than wrap the code with the <% %> syntax.
About the URL format, you can find more choices of how to build it in:
Passing array through URLs
When writing question on SO, please, put more work on that. You will help us find a quick answer to your question, and you, for wait less for an answer.
If you need something more specific, just ask and I can see if I can answer.

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}"

Sinatra: Array into HTML table

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>

Rails 3 how to deal with constants

I have a constant called PAYMENT_METHODS in venue.rb.
PAYMENT_METHODS = ['Visa', 'MasterCard', 'American Express', 'Diners', 'JCB', 'Bankomat', 'sodexo', 'MA-Gutscheine']
You can check/uncheck the payment types in a form (payment_options is an integer):
<%= hidden_field_tag "venue[payment_options][]", nil %>
<% Venue::PAYMENT_METHODS.each do |category| %>
<%= check_box_tag "venue[payment_options][]", category %>
<%= label_tag category %>
<% end %>
Now I want to save the selection, but the value of each check box is the name of the payment option. I think I have to somehow add a key an store only the keys.
How do I set keys and save the collection to the database?
Thanks in advance
Make the constant a hash or an array, e.g.
PAYMENT_METHODS = {'Visa' => 1, 'MasterCard' => 2, 'American Express' => 3, 'Diners' => 4, 'JCB' => 5, 'Bankomat' => 6, 'sodexo' => 7, 'MA-Gutscheine' => 8 }
These will now be in a format that you can pass to options_for_select http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-options_for_select.
If you (really) want checkboxes, an array is fine, just loop over using PAYMENT_MTHODS.each_index do |index| to get an iterator that's the value, and then use PAYMENT_METHODS[index].
I have always found it odd that the hash key is the part displayed in the list, but I guess it makes sense that the value is what is associated with the option's value :-).
Save the string value itself nothing wrong with that.
Its better to create a model like PaymentType and just keep id,name and in view render all payment types.This way you can better manipulate all available payment options in future from an admin panel (if needed) rather than going to a code level and changing at the constant.
You can use an element's index as a key. Use Array#index to your advantage.
PAYMENT_METHODS.index("Visa") #=> 0
PAYMENT_METHODS[0] #=> "Visa"
PAYMENT_METHODS.index("Diners") #=> 3
PAYMENT_METHODS[3] #=> "Diners"
A word of caution: This will break if you reorder PAYMENT_METHODS. You are keying an element to it's relative position in the array. Change the array and you change the keys. Avoid trouble by keeping your constants constant.
In regards to
I have always found it odd that the hash key is the part displayed in the list, but I guess it makes sense that the value is what is associated with the option's value :-).
you can get that done by (it was bugging me a bit as well)
<% Post::TECH_CATEGORY.each do |category| %>
<%= label_tag 'name', category[0] %>
<%= check_box_tag 'tech_cat', category[1] %>
<% end %>
It makes sense now that I can see it on the screen. Each object has two values, so...
category[0]
will always be the key you supplied for that specific object you are currently enumerating over
category[1]
will be the value of that same object. Looks way better on the screen.
which looks like in your example above
<label for="name"> Visa </label>
<input id="tech_cat" name="tech_cat" type="checkbox" value="1" />
Cheers,

Resources