Ruby on Rails Activerecord undefined - ruby-on-rails

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 %>

Related

Ordering by date in Ruby on Rails

I am iterating over a set of objects in Ruby on Rails like so :
<% #subject.Association.each do |horse| %>
<tr>
<td>
<%= horse['Name'].to_s %>
<%= horse['Size'] %>
</td>
</tr>
<% end %>
The horse object has a date field, called dateRode.
I would like to order by this field.
I am not a ruby developer, but I tried a number of ways to do this resulting in only syntax errors e.g
<% subject.association.each do |horse|-> { order by "dateRode" DESC } %>
How can I do this in my code without editing ActiveRecords etc?
You can order collection with order method like this:
<% #subject.Association.order(dateRode: :desc).each do |horse| %>
<tr>
<td>
<%= horse['Name'].to_s %>
<%= horse['Size'] %>
</td>
</tr>
<% end %>
Try to replace this:
<% #subject.Association.each do |horse| %>
with
<% #subject.Association.order(dateRode: :desc).each do |horse| %>
Hoping that it would help you.
<% subject.association.each do |horse|-> { order by "dateRode" DESC } %>
The above is a mix of erb and sql which isnt going to work.
The best way to do it is to create a scope in the model which is called by the controller.
model
def self.order_by_date_rode
Model.includes(:association).order("associations.dateRode desc")
end
where Model is the name of your model and association is the name of the association you want to order by.
controller method
def some_method
#subject = Model.order_by_date_rode
end
A less recommended way is to do the sorting in the view
<% #subject.Association.order(dateRode: :desc).each do |horse| %>
the another way is that you can set a default scope for ordering of the association model like below
class Association < ActiveRecord::Base
default_scope { order('dateRode DESC') }
end
so when you do <% #subject.Association it will automatically sort

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.

Using a variables to access elements in each loop

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.

Nested forms in rails for existing objects

In my app, I have a page where I want admin users to be able to update a particular characteristic of my "Package" model, which belongs to both the "Order" model and the "Item" model. It's a little complicated, but I basically want to present in a table all of the Packages belonging to a given Item, ordered in a particular way (that's what my packages_for_log method below does), with two blanks for updating the weight of the item. All the updates should ideally be submitted at once, with a single submit button at the bottom of the page. I've attempted a whole bunch of solutions, and my current one is below, but gives this error when I visit the page in my server:
undefined method `actual_lbs' for #<ActionView::Helpers::FormBuilder:0x007ff67df6c9c8>
The error's confusing to me, cause I was hoping that I was calling that method on the package instance, not a helper. Bit confused. At any rate, my code is below. The relevant section of the view:
<% form_for(#item) do |a| %>
<% #item.packages_for_log.each do |p| %>
<%= a.fields_for p do |i| %>
<tr>
<td><%= p.order.name %></td>
<td><%= p.order.processed_notes %></td>
<% if p.order.user %>
<td><%= "#{p.order.user.name.first(3).upcase}-#{p.id}" %></td>
<% else %>
<td><%= p.order.id %></td>
<% end %>
<td>
<%= i.text_field :actual_lbs %>
</td>
<td>
<%= i.text_field :actual_oz %>
</td>
<%= i.hidden_field :true_weight, value: (i.actual_lbs + i.actual_oz/16) %>
</tr>
<% end %>
<% end %>
<% end %>
Relevant section of the package.rb model file:
attr_accessible :order_id, :price, :true_weight, :actual_lbs, :actual_oz
attr_accessor :actual_lbs, :actual_oz # These two are virtual attributes for the above calc
And I added resources :packages to my routes file.
Any idea what I'm doing wrong? It's important to me that I loop through to create a table based on "p" and then edit that same "p" object. Just not sure how to do it. Pretty new to Rails.
I think your problem is this line:
<%= i.hidden_field :true_weight, value: (i.actual_lbs + i.actual_oz/16)
You need to put p.actual_lbs and p.actual_oz
EDIT: By the way, you probably need to move the true weight calculation to your controller action (CREATE action). I don't think :true_weight will get passed as you intended it to, using the above method.

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