Rails convention for case statement in view - ruby-on-rails

I am new to ruby and rails so thought I'd ask a question on conventions.
I have a view which produces a list of items in a table and I was asked to make a change and in doing so have added a case statement to the view which I don't think is the correct way of doing things so thought that I would double check.
The change I made was just to add a class to the tr depending on the value of the last table column.
list.rhtml
<table width="100%">
<tr>
<th style="width: 80px;">ID #</th>
<th>Organisation</th>
<th>Product</th>
<th>Carrier</th>
<th>Carrier Ref</th>
<th>Post Code</th>
<th>Status</th>
</tr>
<%= render :partial => 'circuit/list_item', :collection => #circuits %>
</table>
list_item.rhtml
<%
# code I have added
#tr_class = ''
case list_item.status
when 'Handover'
#tr_class = ''
when 'Unprocessed'
#tr_class = 'high_priority'
when 'Ceased'
#tr_class = 'low_priority'
else
#tr_class = ''
end
# end of newly added code
%>
<!-- the class part is new aswell -->
<tr class="<%= #tr_class %>">
<td><a href='/circuit/update/<%= list_item.id %>'><%= list_item.id_padded %></a></td>
<td><%= list_item.organisation.name if list_item.has_organisation? %></td>
<td><%= list_item.product_name %></td>
<td><%= list_item.carrier.name %></td>
<td><%= list_item.carrier_reference %></td>
<td><%= list_item.b_end_postcode %></td>
<td><%= list_item.status %></td>
</tr>
Is there a Rails pattern or convention that can get the case statement out of this view?

If understand properly your question, I think you should put the case statement inside a helper function:
app/helpers/list_helper.rb
module ListHelper
def tr_class_for_status(status)
case status
when 'Unprocessed'
'high_priority'
when 'Ceased'
'low_priority'
else
''
end
end
end
_list_item.rhtml
<tr class="<%= tr_class_for_status(list_item.status) %>">

Related

How to display value of a field from a different table by using the value of a different column in another table

I realize the heading is a little confusing but my problem is quite simple. I hae two models in my rails 5 app. User and Expense. Each expense belongs_to a user. I have an index page where all expenses are being listed. I can list the user IDs for each expense from the expenses table but I want to instead look up the name of the user (in column username) in the users table and display it with the expense instead. The view I have written is below. But it doesn't work.
<p id="notice"><%= notice %></p>
<h1>Teamjournals</h1>
<table style="padding: 2px; width: 50%" border="2px" align="center">
<thead>
<tr>
<td align="center"><%= link_to new_expense_path, :class =>"btn btn-success btn-wide" do%>Add New Expense<% end %></td>
</tr>
<tr>
<th>User</th>
<th>Expense Date</th>
<th>Currency</th>
<th>Expense Amount</th>
<th>Description</th>
<th colspan="1"></th>
</tr>
</thead>
<tbody>
<% #expenses.each do |expense| %>
<tr>
<td><%= User.joins(:expense).where('expense.user_id = ?', #user.id) %></td>
<td><%= expense.expense_date %></td>
<td><%= expense.currency.currency %></td>
<td align="right"><%= expense.expense %></td>
<td><%= expense.description %></td>
</tr>
<% end %>
</tbody>
</table>
Ok so in your iteration over #expenses you have this line:
<%= User.joins(:expense).where('expense.user_id = ?', #user.id) %>
you can change it to this:
<% user = expense.user %>
Note that I'm using <% not <%= because I'm just trying to assign a variable, not print the output to html.
Then after defining user you can say <%= user.name %>.
You should read a bit more about active record associations, but here's a few side comments about the query you've shown
User.joins(:expense).where('expense.user_id = ?', #user.id)
In this case, you should use the method generated by belongs_to instead of writing a query. But in situations where you do want to write a custom query, you should only be using where when you want to get an array. In this case you're looking for a single record so you could use find_by. Furthermore, the joins you're doing here is unnecessary
# any of these works
user = User.where('id = ?', expense.user_id).first
user = User.where(id: expense.user_id).first
user = user.find_by(id: expense.user_id)

Empty list of attributes to change on Ruby on Rails

I am trying to submit a grid form like the below one,
show.html.erb
<%= form_for :datadef, url: update_all_vmodule_path do |fdf|%>
<table id="csvfiles" class="display" width="100%">
<thead>
<tr>
<th width="10%">Column No</th>
<th width="20%">Column name</th>
<th width="20%">Data type</th>
<th width="15%">Column format</th>
<th width="10%">Length</th>
<th width="25%">Comments</th>
</tr>
</thead>
<tbody>
<% #datadefrecords.each do |ddre| %>
<%= fields_for "datadef_records[]", ddre do |dr_fld| %>
<tr>
<td><%= ddre.column_no %></td>
<td><%= ddre.column_name %></td>
<td><%= dr_fld.collection_select :column_datatype, Datadef.select(:column_datatype).uniq, :column_datatype, :column_datatype, {:prompt => true} %> </td>
<td><%= dr_fld.text_field :column_format %></td>
<td><%= dr_fld.text_field :column_length %></td>
<td><%= dr_fld.text_field :comments %></td>
</tr>
<% end %>
<% end %>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td colspan="2"><%= fdf.submit 'Save' %> <%= link_to("<button>Cancel</button>".html_safe, cancelmodal_vmodule_path ) %></td>
</tr>
</tbody>
</table>
<% end %>
<% end %>
This the method i am calling it to submit
def update_all
session[:datadef] = nil
#updatedatadef = Datadef.all.where(:id => params[:datadef_records]).update_all(update_all_params)
redirect_to migproject_path(params[:vmodule][:migproject_id])
end
This is the strong parameters
def update_all_params
params.require(:datadef_records).permit( :column_datatype, :column_format, :column_length, :comments)
end
This is how i get the parameters from form
{"utf8"=>"✓",
"authenticity_token"=>"QrX8JYYYQOlfwKgAABJd0+A7VpugS2Y6n8doDsuKqeM=",
"datadef_records"=>{"12"=>{"column_datatype"=>"varchar",
"column_format"=>"2",
"column_length"=>"2",
"comments"=>"2"},
"13"=>{"column_datatype"=>"varchar",
"column_format"=>"2",
"column_length"=>"2",
"comments"=>"2"}},
"commit"=>"Save",
"id"=>"2"}
But i get this "Empty list of attributes to change" error which is not allowing me to write it in table. And i am not able to identify what could be the error.
Thanks in advance.
I think the problem is to do with your use of update_all, although I'm not 100% sure as to the syntax of the problem.
From what I understand, update_all needs a hash of actual params to populate your data; even then, it will only update what you pass to it (kind of like update_attributes).
Here's a good reference:
data = params[:datadef_records]
#updatedatadef = Datadef.update(data.keys, data.values)
This negates the use of your strong_params, which I'd recommend using. I'd have to spend some time thinking about getting it to work.

Ruby on rails: filtering search box

I am creating a rails application that replicates an online dictionary. I have already implemented the alphabetical_paginate gem but I want to add a search bar that can filter through the words as you type for the word you're looking for. Is there a gem that could do this or is there a straight forward way of filtering with a search bar?
My controller looks like this:
def index
#words, #alphaParams = Word.all.alpha_paginate(params[:letter], {:default_field => "all"}){|word| word.word}
end
View:
<%= alphabetical_paginate #alphaParams %>
<table>
<thead>
<tr>
<th>Word</th>
<th>Wordtype</th>
<th>Description</th>
<th colspan="3"></th>
</tr>
</thead>
<div id="pagination_table">
<tbody>
<% #words.each do |word| %>
<tr>
<td><%= word.word %></td>
<td><%= word.wordtype %></td>
<td><%= word.description %></td>
<td><%= link_to 'Show', word %></td>
</tr>
<% end %>
</tbody>
</div>
</table>
Datatables is what you are looking for.
Here are the links to get started:
http://datatables.net/
https://github.com/rweng/jquery-datatables-rails

Rails Links with Model Object Path

I have the following table, and I want the name of my "restaurant" to be clickable and link to the page of that restaurant.
<table class="table table-striped">
<tr>
<th>Name</th>
<th>Adress</th>
<th>City</th>
<th>No. of Recipies</th>
</tr>
<% #city.restaurants.each do |rest| %>
<tr>
<td><%= rest.name %></td>
<td><%= rest.adress %></td>
<td><%= rest.city.name %></td>
<td>5</td>
</tr>
<% end %>
How am I going to add something like rest_path to:
Link text
You could try this :
<%= link_to rest.name, rest %>
If you have defined a resource restaurant in your config/routes.rb, it will target the url given by the helper restaurant_path(rest) (ie /restaurants/id_of_restaurant).
As the restaurant is a child of a city you might want to have an url like /cities/id_of_city/restaurants/id_of_restaurant so you could try the following :
<%= link_to rest.name, city_restaurant_path(#city, rest) %>
Be sure to have this in your config/routes.rb in order to generate the corresponding helpers.
resources :cities do
resources :restaurants
end
Then you will be able to see all the available helpers for your routes using the command 'rake routes' in the terminal.
Okay so I did something like this
<table class="table table-striped">
<tr>
<th>Name</th>
<th>Adress</th>
<th>City</th>
<th>No. of Recipies</th>
</tr>
<% #city.restaurants.each do |rest| %>
<tr>
<td><%= link_to rest.name, rest %></td>
<td><%= rest.adress %></td>
<td><%= rest.city.name %></td>
<td>5</td>
</tr>
<% end %>
</table>
but now the link is very ugly when I hover on it? How do I get rid of that?

Rails 3 each do ignore nil values

I am building an html table that should include name, rating1, rating2, and rating3. rating 1-3 come from different models than name.
resources :names do
resource :rat1,:rat2,:rat3
end
Inside of my html table I'd like to include the ratings from within each of these tables but I would like to automatically skip over or ignore tables that are nil. This is because :names may only have a :rat1 and not a :rat2 or :rat3. My view should look something like this.
<table>
<thead>Name</thead>
<thead>Rating 1</thead>
<thead>Rating 2</thead>
<thead>Rating 3</thead>
<% #names.each do |name| %>
<tr>
<td><%= name.nametext %></td>
<td><%= name.rat1.rating %></td>
<td><%= name.rat2.rating %></td>
<td><%= name.rat3.rating %></td>
</tr>
<% end %>
</table>
Except that if name.rat1 is nil it will either a.) replace the value with N/A OR b.) it will leave this field blank and move on to the next.
What is the cleanest way to do this?
::UPDATE::
So my issue is that the name.rat1 is nil and the name.rat1.rating is an undefined method of a nil class so both of these options will throw the same undefined method of a nil class error regardless of the || or helper method. At least thats what my current tests are showing. Any other options? or different workarounds? I'd like to avoid having to put a validation loop like this for every rat1-3
<% unless name.rat1.nil? %>
<%= name.rat1.rating %>
<% end %>
There has to be a simpler way.
I would probably create a helper method in names_helper.rb
def show_rating(rating)
if rating.present?
rating
else
"default value"
end
end
Then use it in the view:
<%= show_rating name.rat1.rating %>
OFFTOPIC Your table structure is wrong. It should have <thead><tr><th>Name</th><th>Rating1</th>..so on..</tr></thead>
So, in your case you can use the condition while rendering the rating values as:
<table>
<thead>
<tr>
<th>Name</th>
<th>Rating 1</th>
<th>Rating 2</th>
<th>Rating 3</th>
</tr>
</thead>
<tbody>
<% #names.each do |name| %>
<tr>
<td><%= name.nametext %></td>
<td><%= name.rat1.rating || 'N/A' %></td>
<td><%= name.rat2.rating || 'N/A' %></td>
<td><%= name.rat3.rating || 'N/A' %></td>
</tr>
<% end %>
</tbody>
</table>

Resources