Looping through unique (excluding a single column) values in view - ruby-on-rails

I am keeping track of which users edit text files stored as database entries.
I have a credit model that keeps track of the user, file edited, and a timestamp of when the edit occurred.
In my controller, I have a query that selects the editors of an entry, and joins a time stamp from the credit model.
#editors = User.select("name, users.id, credit.created_at").joins("INNER JOIN credits ON credits.user_id = users.id WHERE credit.file_id = " + x)
In my view, I do not want to display duplicate editors, but the unique timestamp that is joined to the user is causing duplicate editors to print
<% #editors.uniq.reverse_each do |e| %>
<%= link_to e.name, user_path(e.id) %>
<%= e.created_at %>
<% end %>
Is there a way that I can exclude a certain column from the uniq comparison in my view?

This is not the cleanest solution. but this is what I would do if I was a time crunch
<% editor_id = 0 %>
<% #editors.uniq.reverse_each do |e| %>
<% unless editor_id == e.id %>
<%= link_to e.name, user_path(e.id) %>
<%= e.created_at %>
<% editor_id = e.id %>
<% end %>
<% end %>
What I am doing here is initializing a variable called editor_id and then check if its the same a the editor id. if its false then it displays the editor
I hope that this helps and puts you in the right track

Related

listing data dependant on associated database

Wasn't sure how to title this question but here it goes.
I have two tables, Hotdesks and Bookings. Users can book a hotdesk.
In my controller I have an array #eastdesks containing all desks with a location of "East".
What I would like to do is to check which of these desks have been booked and display a list of available desks. This is my controller:
#eastdesk = Hotdesk.order("code ASC").where(:location => "East")
#booking = Booking.all
And this is my code so far:
<% #eastdesk.each do |ed| %>
<% #booking.each do |b| %>
<% if b.date == Date.today && b.type == "Hot Desk" %>
<% if b.desk == ed.code %>
<%= ed.code %> (Booked)
<% end %>
<% end %>
<% end %>
<% end %>
This ONLY shows those that have been booked.
I appreciate it is very ugly because I have been playing around. It is quite confusing but the t tables are associated vie the 'desk' column in bookings and the 'code' column in eastdesk. (i.e. booking with desk 553 will link to the desk with code 553) Hope that makes sense. Thanks for the help
EDIT ----
At the moment there are 2 desks in #eastdesk array (E90 and E23). The E90 desk has been booked for today and the E23 desk has not been booked at all. For the code above I am getting the following output:
E90 (Booked)
What I want to show is the desks that have NOT been booked. My Hotdesk model consists of:
has_many :bookings
I was thinking of adding the following to my bookings model but I am not sure as there ar different types of bookings and not all of them belong to a hot desk.
belongs_to :hotdesks
You can create an array holding 'Desk Codes' from booking table and use 'include?' method to check if this array contains the 'desk' value of #eastdeck.
Possible Solution:
#booking.map { |b| #booking_codes.push b.desk } // Creating a temporary array holding 'desk' from #booking
View:
<% #eastdesk.each do |ed| %>
<% #booking.each do |b| %>
<% if b.date == Date.today && b.type == "Hot Desk" && #booking_codes.include? b.desk %>
<%= ed.code %> (Booked)
<% end %>
<% end %>
<% end %>
PS: This may not be the nicest solution, but it may help :)

Rails filtering row by column using select dropdown

I was making a travel vacation application. Searching of places is based on categories from select dropdown.
But I am not able to understand the program logic. I am able to load the content in the database. but can't filter based on certain categories.
I made a scaffold called listing and included certain parameters.
In the database it has a row of 5 columns, namely, place, description, image_url, price, category.
Now, if I create another controller, search, I am not able to load a row based on a category from the select dropdown.
Search_controller.rb
def index
#categories = Listing.find_by_sql("SELECT category FROM listings GROUP BY category").map &:category
#list = params[:category].blank? ? Listing.all : Listing.find_all_by_category(params[:category])
end
index.html.erb
<% form_tag(:action => :index) do %>
<%= select_tag "category", options_for_select(#categories) %>
<%= submit_tag "Filter" %>
<% end %>
<table>
<% #list.each do |list| %>
<tr>
<td><%= list.place %></td>
</tr>
<% end %>
</table>
It does not show the select option.
Also, I tried to do this without select form
Search_controller.rb
def index
#list = Listing.select(:category).map(&:category).uniq
end
Index.html.erb
<% #list.each do |r| %>
<%= r.place %>
<% end %>
It says: undefined method `place' for "sunny":String (where "sunny" is a category)
Basically, how do you get the row based on a certain column value. And, will the logic also apply to two select dropdowns?
I know I am close, but somethings not right. Please assist me.
Thanks a lot.
You are missing = before form_tag. Should be:
<%= form_tag(:action => :index) do %>
<%= select_tag "category", options_for_select(#categories) %>
<%= submit_tag "Filter" %>
<% end %>

Rails comparison not working

In Rails, have a workorders table. Each workorder can have children workorders. I'm trying to create dropdown links to sibling workorders. I'm testing by looking at workorder.id = 30. It has a sibling workorder.id = 20. I don't want to display a link to the same workorder the user is looking at (30).
So I put in a test <% if child.id != #workorder %>. But, the 30 link still displays. I added some logger code to see what's going on.
This is my code:
<li class="dropdown-header">Siblings Links</li>
<% Workorder.find(#workorder).parent.children.each do |child| %>
<%= logger.info 'LOOK HERE ' %>
<%= logger.info child.id %>
<%= logger.info #workorder %>
<% if child.id != #workorder %>
<li><%= link_to child.id_desc, tasks_index4_path(:workorder_id => child) %></li>
<% end %>
<% end %>
The log shows:
LOOK HERE
30
30
LOOK HERE
30
20
Yet the link_to for 30 shows up.
Thanks for the help!
use #workorder.to_i in the comparison
#workorder presumably is a Workorder object. As such, in order to compare the #workorder to the child.id, you'll need to access the id attribute on #workorder in order to make the correct comparison:
<% if child.id != #workorder.id %>

grouping children by parent attribute

Here's what I am trying to achieve:
Group_x.name
member1.name -- member1.join_date -- etc
member2.name -- member2.join_date -- etc
...
Group_y.name
member1.name -- member1.join_date -- etc
member2.name -- member2.join_date -- etc
...
What I'm going for is really very similar to this although the implementation there doesn't work for me.
I've gotten this far in my controller:
def index
# https://stackoverflow.com/a/17835000/2128691
#user_group_ids = current_user.student_groups.map(&:id)
#students = Student.where('student_group_id IN (?)', #user_group_ids)
# https://stackoverflow.com/a/10083791/2128691
#students_by_group = #students.uniq {|s| s.student_group_id}
#title = "All students"
end
and calling the following in my view -
<% #students_by_group.all.each do |x| %>
<p>
<%= "#{x}" %>
</p>
<% end %>
gives me a list of all student objects. if i call <%= "#{x.name}" %> or <%= "#{x.created_at}" %>, etc, I get the correct information, and everything is great.
But now that I have all this information, how can I put the group.name (in my code it would be x.student_group.name) as a header for all of the students for which that group_name is true?
I think you need to use group_by on #students_by_group like this:
#students_by_group = #students_by_group.group_by { |s| s.student_group }
This would return a hash with the keys being the student group objects and the values being the students that belongs to this group, then you can do this in your view:
<% #students_by_group.each do |group, students| %>
<h3><%= group.name %></h3>
<% students.each do |x| %>
<p>
<%= "#{x}" %>
</p>
<% end %>
<% end %>
As an additional note, the group_by would fire a query for each student, so you may want to eagerly load the student group for each student like this for some performance gain:
#students = Student.where('student_group_id IN (?)', #user_group_ids).includes(:student_group)

Rails. Check if ANY of the attributes in a collection is blank

I have a collection of invoices. One of the attributes is exchange_rate (is used to calculate the currency from US dollars for Mexican pesos). I need to create a warning if even ONE of the records doesn't have an exchange_rate set.
I could check if the exchange_rate of a record in a collection is blank like this...
<% is_blank = false %>
<% #invoices.each do |invoice| %>
<% if invoice.exchange_rate.blank? %>
<% is_blank = true %>
<% end %>
<% end %>
<% if is_blank %>
shoot warning: all of the invoices must have an exchange rate in order
to calculate pesos total
<% end %>
What is a more Railsy way of writing the above?
Simply like this, using the Enumerable#any? method:
<% if #invoices.any? { |i| i.exchange_rate.blank? } %>
shoot warning: all of the invoices must have an exchange rate in order
to calculate pesos total
<% end %>

Resources