I have a model student with a subject and grade attribute. A student can have many subjects and grades, and what I'd like to do is be able to publish the 2nd or 3rd subject listed for a specific student.
For example, the user searches for a student, then clicks on the student, which brings them to a separate page listing information about that particular student (ie, student id:1). Is there code I can add to the view to list the nth item from the subject and grade attributes?
I looked online here and found similar questions, but those solutions related to the model, not the attributes. For example, one solution recommended using the limit method in the controller and another recommended using the following code:
<% firm.state_of_business.split(',').each_with_index do |state, index| %>
<td> <b>State <%= index + 1 %></b> <%= state %>
This seems to work well, when you don't have a specific model selected. When you select a particular model(ie, student id:1), this doesn't seem to work. At least not for me. Right now my code below is showing the first item. How might I get it to list subject 1 & grade 1, subject 2 & grade 2, subject 3 & grade 3, etc.. See sample code below. Please note, that I tried other solutions on here, but couldn't get them to work, which made me think that my problem might be different than the ones previously presented. Thanks for your help.
View Code
<h2>Students</h2>
<p> Student:
<%= #student.name %>
</p>
<table>
<tr>
<th> Subject </th>
<th> Grade </th>
</tr>
<tr>
<td><%= #student.subject %> </td>
<td><%= #student.grade %> </td>
<tr>
</table>
Controller Show Method
def show
#user = current_user
#student = Student.find(params[:id])
end
Desired Output
Student: Matt Jones
Subject Grade
Math 95
History 90
English 91
Try adding this code:
<%= #student.grade.split(',')[0] %>
The [0] will publish the first item in the array. [1] will publish the 2nd item, etc. That should work.
I guess you can just create another model called Subject and add has_many :subjects in class Student.
In class Subject, you can add this line belongs_to :student.
And then you can do this something like this:
<% #student.subjects.each do |subject| %>
<tr>
<td><%= subject.name %> </td>
<td><%= subject.grade %> </td>
<tr>
<% end %>
Just to make it clear, Subject model contains attribute name and grade in above example.
Related
I have 3 models I am working with and trying to find the most frequent items between two models that are not related, but have a third table that is.
My 3 models are:
Visits (has_many Diagnoses)
Diagnosis (belongs_to Visit)
Prescriptions (belongs_to Visit)
Given a specific diagnosis, I want to know what drug is most commonly prescribed. Since Diagnosis and Prescriptions don't have a direct relationship I am lost. Below is my current code
This gets my top diagnoses
#top_diag = Diagnosiswork.group("diagnosis").order("count_diagnosis_id desc").limit(10).count("diagnosis_id")
This is in my view
<tbody>
<% #top_diag.each do |diagnosis, count| %>
<% top_visits = Diagnosiswork.where(diagnosis_id: diagnosis.id) %>
<% top_prescription = Prescription.where(visit_id: #top_visits) %>
<tr>
<td><%= count %>: <%= diagnosis.id %></td><td><strong><%= diagnosis.name %></strong></td>
<td>
<% top_prescription.each do |prescription| %>
<%= prescription.medicine.full_name %>
<% end %>
</td>
<td><span class="badge badge-success">Active</span></td>
<td>
</td>
</tr>
<% end %>
</tbody>
This gets me a list of drugs, but it is the same list for every diagnosis. My current thought is to get the Visits where these diagnosis are used the most, and then use a query similar to my top_diag that uses a where clause singling out certain visits.
Thanks so much in advance!
Editx2: The short short version: I think I found my answer:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for
Under heading One-To-One , I think this is what i want?
If so I will just close this out.
EDIT: I found this here:
http://railscasts.com/episodes/196-nested-model-form-part-1?autoplay=true
This is close to what I want, but it has many things under the survey (in my case a group) and while I will have many addresses for a group this is in a different area (as locations), but in the main form when the group is created I have ONE address that is the billing address for a group. So I am not sure how to have like the form look all nice and update the #group.billing_address as described below.
I have a model called Group, in it it has a billing address. This billing address is of type 'Address'. In the group model it looks like
belongs_to :billing_address, class_name: 'Address', foreign_key: 'billing_address_id'
In my group_test.rb file I can test this functionality very easily:
test 'can add a billing address to a group' do
group = Group.new
group.group_name = 'Group test with provider'
adr = Address.new
adr.city = 'Las Cruces'
adr.state = 'New Mexico'
adr.zip = '88012'
adr.address_line_one = '382 Dark side of moon'
adr.address_line_two = ''
adr.save
group.billing_address = adr
group.save
assert_not_nil group.billing_address, 'Group did not have any billing address'
end
My question is how would I do the above in a form? Since my controller group_controller.rb does this on new:
def new
#group=Group.new
end
It doesn't do anything like:
def new
#group=Group.new
#group.billing_address.new
end
To which in my view input tags for the form can't look something like:
<table>
<tr>
<th>
<%= f.label "Group Name" %>
</th>
</tr>
<tr>
<td>
<%= f.text_field :group_name , size: 50 %>
</td>
</tr>
<tr>
<th>
<%= f.label "Billing Address City" %>
</th>
</tr>
<tr>
<td>
<%= f.text_field :billing_address.city, size: 50 %>
</td>
</tr>
</table>
The above does not work. I didn't expect it to, just trying to demonstrate what I am trying to do. Is even my thinking right? or do I have to split the data up like I do sort of more in my test, and do it according to this answer I found on multiple models in a form:
Rails - User Input for Multiple models on a single form - How
Get the data that way and hook it back together in the controller on the create or update method?
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.
I am still fairly new to Rails and fairly sure the way I'm attempting to go about this is inefficient or just plain silly, but here's what I'm trying to accomplish. I have 2 models, Cases (patient case files) and Inventories (medical transplant materials used in Cases).
class Case < ActiveRecord::Base
has_many :inventories
accepts_nested_attributes_for :inventories, :reject_if => :all_blank
end
class Inventory < ActiveRecord::Base
belongs_to :case
end
Inventories are created through a separate process and the goal is to associate them with a Case through the Case form. What I am trying to do is put a table on my Case form that lists the available Inventories along with checkboxes to select the desired Inventories to associate with the Case being created. This is further complicated by the fact that I need to be able to include nested fields for a couple of attributes on each Inventory (:case_price and :case_ship_price). I had previously done this in a very roundabout way using a has_many through association and storing those attributes on the pivot table, but it involved some hacky code to capture the field inputs from params and then save them through this block:
class CasesController < ApplicationController
def create
#case = Case.new(params[:case])
if #case.save
#case.case_lineitems.each do |li|
li.update_attributes(:price => params[:lineitem_price][li.inventory_id.to_s],
:shipping_cost => params[:lineitem_shipping][li.inventory_id.to_s])
end
redirect_to #case
else
render 'new'
end
end
end
This felt extremely clumsy and I was worried about problems it might cause, so I wanted to give a simple has_many, belongs_to relationship a try. However, I'm not sure if the typical <%= check_box_tag :inventory_ids, inventory.id, #case.inventories.include?(inventory), name: 'case[inventory_ids][]' %> works for that type of relationship. Here is what this section of my form looks like presently:
<table>
<thead>
<tr>
<th></th>
<th>Product</th>
<th>Serial #</th>
<th>Price</th>
<th>Shipping</th>
</tr>
</thead>
<tbody>
<% #inventories.each do |inventory| %>
<tr>
<td>
<%= check_box_tag :inventory_ids, inventory.id, #case.inventories.include?(inventory), name: 'case[inventory_ids][]' %>
</td>
<td><%= inventory.product.name %></td>
<td><%= inventory.serial_num %></td>
<%= f.fields_for :inventories, inventory do |inv| %>
<td>
<%= inv.text_field :case_price %>
</td>
<td>
<%= inv.text_field :case_ship_price %>
</td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
This results in the first checkbox defaulting to checked, and if I leave all unchecked, all of the inventories become associated upon submission. Checking only a subset results in an exception along the lines of Couldn't find Inventory with ID=206 for Case with ID=. Finally, checking all of the Inventories seems to result in the associations and nested attributes saving correctly.
How do I clean this up so that it works as desired? And if I need to go back to a has_many through relationship, is there a better way to save attributes on the pivot table on the same form that creates the row on pivot table? I'd really appreciate any help with this, as no amount of searching has gotten me out of this challenge.
I have the following code to display any comments that a user has made in a table on the users show page. The code works fine and a table is diplayed with all of the users comments and the permits they belong to. Currently the table displayed shows the permits in the order they were created by the user. I would like to arrange the table so that the permit column is displayed in alphabettical order instead of when they were created. Im not sure if I need to adjust this code or something in the controller.
<% if #user.comments.exists? then %>
<b>Comments:</b><br />
<table>
<tr>
<th>Permit</th>
<th>Comment</th>
</tr>
<% #user.comments.each do |comment| %>
<tr>
<td><%= link_to comment.permit.name, comment.permit %></td>
<td><%= comment.body %></td>
</tr>
<% end %>
</table>
<% end %>
Use the ActiveRecord order method.
Check the official documentation here: http://guides.rubyonrails.org/active_record_querying.html#ordering
In your case, that would be something like:
<% #user.comments.order('name').each do |comment| %>
> sorted_permits = #user.permits.sort
This gives you a list of permits, ordered naturally (i.e. if they are String values, they are sorted alphabetically, if they are numeric values, they are sorted from lowest to highest). You can do that in your view, or more typically, in your controller.
So, if I have a list of permits such as:
permits = ["Fishing", "Hunting", "Reading", "Driving"]
Then when I can do the following:
> permits.sort
=> ["Driving", "Fishing", "Hunting", "Reading"]
NOTE that .sort returns a copy of the list, in sorted order, while the similar .sort! modifies the original list, reordering it permanently (in memory), but does not change the order/IDs of the permits in the database.
See: http://www.ruby-doc.org/core/classes/Array.html#M000244
Using the :order option directly on the relation definition should do the trick:
class Comment < ActiveRecord::Base
has_many :permits, :order => 'name DESC'
end