Using a variables to access elements in each loop - ruby-on-rails

This is hard to explain.
I have a form builder (Question model) that creates form fields that belong to a specific event, these questions appear on the registration page handled by the Registration model.
There are default form fields that always stays the same and then X additional ones created by the form builder. The Question model has the field "db_field", which gets populated with the corresponding db field in the Registration model.
Note that the questions also have position_ids.
What I'm trying to achieve is to get answers display under the corresponding headings in a table in the index page, my view looks like this
<% #questions = Question.where(:event_id => #event.id).order(:position) %>
<table class="table table-striped table-bordered table-condensed">
<tr>
<% #questions.each do |q| %>
<th><%= q.question %></th>
<% end %>
</tr>
<% #event.registrations.each do |r| %>
<tr>
<% #questions.each do |q| %>
<td><%= r.(q.db_field) %></td>
<% end %>
</td>
</table>
So basically I need 'q.db_field', which might be 'title', for instance, to call r.title - if that makes sense.
I've tried a few things, but nothing seems to work.
Thanks in advance,
Charl

You can use Object#send to invoke methods on a given object.
See http://ruby-doc.org/core-2.0/Object.html for more info.
so replacing <%= r.(q.db_field) %> with <%= r.send(q.db_field) %> will allow you to use the field name from the DB. If you need to specify arguments for the method being called, you can pass them in after the method name. Per the docs, method name can either be a symbol or a string, if it is a string, it will be converted to a symbol for you.

Related

Posting string data into arrays from Rails views (forms)

I've been trying to figure out how to post a string into an array from a user input text field that is part of a form. The push and << methods work fine over the console, but I couldn't manage to save any string data into arrays from my forms. It always reports a type mismatch like this:
Attribute was supposed to be a Array, but was a String.
What is the appropriate way to deal with this ?
EDIT code example:
the array:
serialize(:name, Array)
Let's say that the form contains just a simple text field, nothing else. How would I store the input data into the array above ? Basically what's the correct format of this piece of code:
<%= form_tag(grids_path , method: "post") do %>
<table id="grid">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td><%= text_field(:grid, :name) %></td>
</tr>
</tbody>
</table>
<%= submit_tag("Save") %>
<% end %>
If you simply want to store a param into and array, you should do something like this:
<%= text_field_tag 'grid[name][]' %>
then the params['grid']['name'] will contain an array of strings
In your view:
<%= text_field_tag :my_string_a, 'String A' %>
<%= text_field_tag :my_string_b, 'String B' %>
In your controller:
my_array_of_strings = []
my_array_of_strings << params[:my_string_a]
my_array_of_strings << params[:my_string_b]
puts my_array_of_strings
Hope this works.

How do I extract relevant attribute values from a Rails habtm collection object in my view

I have 2 models:
1) upload
2) date_range
there is an intermediate join table as these models are associated by a many to many relationship thus, each is habtm to the other.
In my view for uploads(index.html.erb) Im trying to show all the date_ranges for a particular upload as follows:
<tr>
<th>File name</th>
<th>Upload Date, Time, Filename</th>
<th>Type</th>
<th>Dates in Upload</th>
<th>Total Rows</th>
<th>Rows Entered in DB</th>
<th>Percentage Completed</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% #uploads.each do |u| %>
<tr>
<td> <%= u.sourcedata_file_name%></td>
<% path_arr = u.f_path.split("\/")%>
<td><%= path_arr[-3..-1]%></td>
<td> <%= u.sourcedata_content_type%></td>
=>> <td> <%= u.date_ranges.inspect%>
<td> <%= u.total_rows%></td>
<td> <%= u.rows_completed%></td>
like so.
This shows up as follows on the browser:
In my "Dates in Upload" column I want to only show some string with dates like this:
"2013-12-25, 2013-12-26" how do I only get these extracted out of the ActiveRecord::Associations::CollectionProxy object as it shows in the image?
Thanks
Use u.date_ranges.pluck(:date_range) to get just the date ranges.
you can then pretty it up with
u.date_ranges.pluck(:date_range).each {|range| puts range}
if you want them in a column.
I see you want them side by side, so it looks like there will only be two because it's a "range" so:
<%= u.date_ranges.pluck(:date_range).first %>, <%= u.date_ranges.pluck(:date_range).last %>
The simplest thing would probably be to add a to_s method in your DateRange model:
def to_s
date_range.to_s
end
And in your view, something like:
<%= u.date_ranges.map {|dr| dr.to_s }.join(', ') %>
However, that's really a bit too much code to put right in the view. Better would be to move that to a helper, or even use a presenter pattern. The 'draper' gem can make this kind of thing very easy, so you can do the same transformation in multiple places in your app, and keep your view template much cleaner.

Ruby on Rails Activerecord undefined

I am new to the Ruby on Rails.
in controller
#academic_record = AcademicDetailWeb.where(:term => #sel_term, :sysid=>session[:user_credentials_sysid])
in the view
<table>
<tr>
<th>CRN</th>
</tr>
<%#academic_record.each do |a|%>
<tr>
<td>
<%= #academic_record.crn %>
</td>
</tr>
<%end%>
</table>
it give me "undefined method `crn' for activerecord"
I tried to use
#academic_record.first.crn
and it works, but only shows the first record
How could I modify it to become several row records?
You are referring to the collection of records while inside the loop. Change that to refer to one element of the collection:
<% #academic_record.each do |a|%>
<%= a.crn %>
<% end %>
#academic_record is a collection of the academic details according to your condition and inside each collection each data contains crn attribute..crn is an attribute of each member of this collection, not the collection as a whole, thats why when you use #academic_record.first.crn it gives crn of first element inside that collection and when you use #academic_record.crn it gives you undefined method, cuz there isn't any crn attribute of the collection as whole so you should do something like
<% #academic_record.each do |ar|%>
<%= ar.crn %>
<% end %>

The "Rails" way to submit an unspecified number of user inputs into params

I am working in Rails to allow an administrator to endow fictional money to users. In my mind, there are the following steps:
An administrator asks the DB for a list of users
The administrator specifies the amount of money given to each user
The DB adds the specified amount to each user's account and saves
I have a code that works but is inelegant. I was wondering what the correct "Rails" way to approach this scenario would be. Specifically, I am seeking your help on the following points:
How to elegantly process an indeterminate number of inputs from the user (currently, I generate the form using for loop on all users)
How to send variables used in one action to another (currently, I am using the hidden_field_tag, but I find it a bit cumbersome)
Whether there is a way to avoid calling .to_i, .to_s, .to_f (since it seems quite unnecessary)
How to maximize performance by reducing unnecessary db query
(currently, I am storing the size of users in #size)
My most important questions are #1 and #2. I would appreciate any hint / help. Thank you very much!
#This the action in the controller corresponds to the first bullet point
def index
#users = User.all
#size = #users.length
end
#This the action in the controller corresponds to the third bullet point
def provide_currency
array = *(1..params[:size])
for i in array
user = User.find(i)
user.money += params[i.to_s].to_f
user.save
end
redirect_to admin_path
end
#This is the index.html.erb that corresponds to the second bullet point
<%= form_tag provide_currency_path do %>
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>User</th>
<th>E-mail</th>
<th>New endowment</th>
</tr>
</thead>
<tbody>
<% for user in #users %>
<tr>
<td><%= user.name%></td>
<td><%= user.email%></td>
<td>
<%= number_field_tag (user.id) %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= hidden_field_tag "size", #size %>
<%= submit_tag "Provide", :class => "btn" %>
<% end %>

Returning a hash from controller to a view using a helper

Warning I'm brand new to rails!
While reading through a tutorial it has asked me to place a hash of string keys with decimal values into the products action method (My assumption they are talking about the "def products" in the controller.
In reguards to using the products method in the controller did I place my hash correctly?
In reguards to the placing the information from the hash into a table do I even need the helper method or is there a better way?
My helper needs help and doesn't format the data correctly using .html_safe I
This is what I have so far in my controler:
def products
#hard coded as products in controller
#stuff = {"a"=>200.00, "b"=>150.00, "c"=>100.00, "d"=>9.00, "e"=>15.00, "f"=>20.00 }
end
This is what I have in my product.html.erb file
<%= form_tag(products_path) do %>
<table id="aboutus_table">
<%= products_tabler() %>
</table>
<% end %>
and then the helper...it needs help
def products_tabler
snowholder = #snow_stuff.each {|key,value|puts "<tr><td>#{key}</td><td>#{value}</td><tr>"}
return snowholder
end
puts is probably a mistake, you don't really want to print to standard out in a web service. See if this works?
def products_tabler
snowholder = ""
#snow_stuff.each {|key,value| snowholder += "<tr><td>#{key}</td><td>#{value}</td><tr>"}
return snowholder
end
I realize this is a tutorial, but using a helper that emits hardcoded html is not an improvement over having the html in the view itself.
In this case, it's really simple to do it in the view:
<table id="aboutus_table">
<% #snow_stuff.each do |key, value| %>
<tr>
<td><%= key %></td><td><%= value %></td>
</tr>
<% end %>
</table>
If you really wanted to separate the creation of the rows, a collection partial would be better. Then Rails does the iteration for you. Use this technique when you've got real data (i.e. ActiveRecords instead of hashes).
<table id="aboutus_table">
<%= render :partial => "row", :collection => #stuff %>
</table>
Then the _row partial would contain:
<tr>
<td><%= row.name %></td><td><%= row.value %></td>
</tr>

Resources