Rails view and pulling data within a loop - ruby-on-rails

<% #blog.blog_comment_types.each do |blog_comment_type| %>
<tr>
<td><%= blog_comment_type.comment_type_id %></td>
<td>Comment name goes here</td>
</tr>
<% end %>
I want to be able to output the comment name based off the comment_type_id.
I an looping through the blog_comment_type table, I want to use the "comment_type_id" column so I can pull from the following table: comment_type which has the name field I want to output. The comment_type table has an id which is the referenced comment_type_id being looped through.
Is there a best practice in Rails to do so within a view?
Tbl: comment_type
fields:
id
name
tbl: blog_comment_type
fields:
id
comment_type_id (this is the matching id in the comment_type table).
Thanks!

In Rails and beyond, the best practice is not to do this in a view. Instead, if you setup your Blog object so it knows about the comment types associated with it, then the problem becomes pretty simple:
class Blog
has_many :blog_comment_types
....
end
then in your view:
<% #blog.blog_comment_types.each do |blog_comment_type| %>
<tr>
<td><%= blog_comment_type.id %></td>
<td><%= blog_comment_type.name %></td>
</tr>
<% end %>

Related

Get specific item from object

I'm attempting to return the specific hospital name associated to a patient but keep getting errors.
Models:
Hospital
has_many :patients
Patients
belong_to :hospital
When rendering my page I call the controller:
def list_patients
#patients = Patient.all
end
In my view I print out each patient and their information:
<% #patients.each do |patient| %>
<table>
<tr>
<td><%= patient.first_name + "," + patient.last_name %></td>
<td><%= patient.ssn %></td>
<td><%= patient.dob %></td>
<td><%= patient.hospital.name%></td>
</tr>
</table>
The above returns an "undefined method for name". If I remove name I can see that a object (<Hospital:0x007fa1d9530138>)
is returned, but I'm unable to then access the specific attributes within the object.
I can return the specific hospital ID, if I do something like:
patient.hospital_id
but am then stuck on how to get to the hospital name.
Is your code equal to the pasted one?
If so, is belongs_to and not belong_to
If you also can't do Hospital.first.patients in the console, make sure you have a hospital_id in you patient model

Referencing a model's Show View form another model's Index view

In the Color Index View, the following produces a clickable link that takes me to the Color Show View.
<% #colors.each do |color| %>
<tr>
<td><%= link_to color.color_name, color_path(color) %></td>
in the model, I have:
class Color < ActiveRecord::Base
belongs_to :product
I also have a Product Index View, and I want to create a clickable link to the Color Show View, but I can't make it work.
This does not work (for one thing, color_name is not the primary key in the color table:
<% #products.each do |product| %>
<tr>
<td><%= link_to product.color_name, product.color_name, color_path(color.color_name) %></td>
in the model, I have:
class Product < ActiveRecord::Base
has_many :colors
This is not working and I'm getting an error when I try the Color Index View, something like:
undefined local variable or method color
Any ideas?
Solution:
Here's what ended up working:
<% color_id = Color.find_by_color_name(product.color_name) %>
<td><%= link_to product.color_name, color_path(color_id) %></td>
It could also obviously be done on a single line, but two lines makes the code more readable (I think)
What I don't understand is why someone found it necessary to downgrade the question.
color.color_name is giving you error because you don't have color object on Product Index View.
Try <td><%= link_to product.color_name, product.color_name, color_path(product.color) %></td> if there is one-to-one relationship
Try <td><%= link_to product.color_name, product.color_name, color_path(product.colors.first) %></td> if there is one-to-many relationship
Your Product has_many colors. Therefore, your code should be something like this:
<% #products.each do |product| %>
<tr>
<% product.colors.each do |color| %>
<td><%= link_to color.color_name, color_path(color) %></td>
<% end %>
</tr>
<% end %>
It iterates on the colors of your each product and shows link to their show path.
Caution: Probably subjected to N+1 problem. Above is just supposed to give you direction.

Using has_many / belongs_to to access info in controller - Ruby on Rails

This is probably a very simple question, I apologise - I'm new to rails.
I've got 2 controllers - customers and orders. I've got it so that when a customer places an order, their id is passed in a hidden field, so that the customer_id field in the orders table has their id. So all orders have the id of the customer who placed it. What I'm trying to do is have the show view for the customers display all their orders - so all the orders with their id.
I've got the customer has_many orders and orders belong_to customers etc. How do I reference the customers/orders to extract the right info? And do I need to put extra info in the show action on the controller? I've tried everything I can think of! So far, I've been able to get a hash of all the info to appear in the show view, but I can't get individual bits of info to appear - e.g. order.price.
I basically want a table of the order details in the customers show view - order price, date placed etc. Any help would be much appreciated, thanks!
Edit: I now have this - but can't get the line_items bit to work. The relationships work like this: customer has many orders, orders have many line items, line items belong to products. I suspect the reason it's not working is because of the belongs_to.
<% #customer.orders.each do |order| %>
<% order.line_items.each do |line_item| %>
<tr>
<td><%= line_item.created_at %></td>
<% line_item.products.each do |product| %>
<td> <%= product.name %></td>
<% end %>
<td><%= order.email %></td>
</tr>
<% end %>
<% end %>
You shouldn't need to add anything to the controller show action.
In your customer show view you presumably have access to a #customer object. Because of your has_many, that will have a collection #customer.orders. So, in the view, you can do something like
<table>
<thead>
<td>Item</td>
<td>Quantity</td>
<td>Price</td>
<td>Date Placed<td>
</thead>
<% #customer.orders.each do |order| %>
<tr>
<td><%= order.item.name %></td>
<td><%= order.quantity %></td>
<td><%= order.price %></td></tr>
<td><%= order.date_placed %></td>
</tr>
<% end %>
</table>
Obviously I'm making up the possible order fields you'd want to display, but this should give you the idea.
In your show action:
def show
#customer = Customer.find(params[:id])
end
In your routes.rb:
resources :customers
In your view:
<table>
<% #customer.orders.each do |order| %>
<tr>
<td><%= order.id %></td>
<td><%= And Other Your Order Fields %></td>
</tr>
<% end %>
</table>

How can I display data for the current view from a different table

I have two tables:
Chords - |id|chord|name|rating|artist_id|
Artists - |id|artist|
An Artist has many Chords, and thus a Chord belongs to an Artist.
And in the index page for "chords" I want to display chord, name, and rating from Chords table and the artist from the artists table
This is the code for the Chord's index.html.erb:
<table border="1">
<% #chords.each do |chord| %>
<tr>
<td><%= chord.artist.artist %></td>
<td><%= link_to chord.name, chord %></td>
<td><%= chord.rating %></td>
<td><%= chord.created_at %></td>
</tr>
<% end %>
</table>
The error message is:
undefined method `artist' for nil:NilClass
Actually, at first it worked, but when I started to create the "new.html.erb" page and the create and new actions, it stopped working, that's why this is so confusing to me!
Since chort.artist can be null, you should change chord.artist.artist to chord.artist.try(:artist) which is shorthand for
if chord.artist.nil?
nil
else
chord.artist.artist
end
You could use
<td><%= chord.artist.artist unless chord.artist.artist.nil? %></td>
In the view is no the right place to do it but what you need to do is find the artist with the ID given in the CHORDS like this
#currentArtist = Artist.find(:all, :conditions => {:protectora => Chord.artist_id})
Then when you find it by the ID given in the CHORD and save it in to a variable, you can access it like any other variable so:
#currentArtist.artist
Hope it helps.

Ordering a table column alphabetically

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

Resources