Rails - Unique Array in View - ruby-on-rails

Having a Bit of trouble displaying unique results from my database. I have a database called "Activities". Each Activity has an associated Sport through sport_id. There may be many activities with the same sport_id.
I want to display a list of all sports linked to the activities database without displaying (for example "Football") twice.
FYI : Venues have many Facilities and Facilities have many Activities.
Controller:
#sports = Sport.all
#activities = Activity.paginate(page: params[:page])
#facilities = Facility.where(venue_id: #venue.id)
View:
<% #facilities.each do |f| %>
<% #activities.find(:all, :conditions => "facility_id == #{f.id} ").each do |a| %>
<li><%= Sport.find(a.sport_id).name %>, (<%= a.facility_id %>)</li>
<% end %>
<% end %>
This shows:
Football, (2)
Hockey, (2)
Hockey, (2)
Football, (5)
I would like to display just:
Football
Hockey
Any ideas?

A simple solution would be to reduce your array with ruby in the view using: uniq!
<% #facilities.each do |f| %>
<% #activities.find(:all, :conditions => "facility_id == #{f.id} ").uniq! { |a| a.sport_id }.each do |a| %>
<li><%= link_to Sport.find(a.sport_id).name, Sport.find(a.sport_id) %></li>
<% end %>
<% end %>
Another way may be to perform a single query on your DB since Sport what you want to narrow down
In controller:
#sports = Sport.joins(activities: [facility: :venue]).where(facilities: { venue_id: #venue.id }).distinct
In view:
<% #sports.each do |sport| %>
<li><%= link_to sport.name, sport %></li>
<% end %>
I am not sure about your DB schema so I went with what I thought you would have done, but it might needs some tweakings.
I hope I helped you.

try to use reject before each
<% #facilities.reject{your condition here}.each do |f| %>

Related

Display title instead of id from search results

I have spent hours on this single problem, I am desperate for help.
The below html displays the correct car name and the car.manufacture_id displays the correct manufacture id, except I need to display manufacture.name and can not figure out how to do that. How do I display car.manufacture.name?
search.html.erb
<% #cars.each do |car| %>
<%= car.manufacture_id %>
<%= link_to car.name, manufacture_path(car.manufacture_id) %>
<% end %>
search_controller.rb
def search
if params[:q].nil?
#cars = []
#manufactures = []
else
#cars = Car.search params[:q]
#manufactures = Manufacture.search params[:q]
end
end
What do your car and manufacture models looks like, can you show the code for them? The schemas would help too. If your models are setup right car.manufacture.name should have worked.
If you do
<% #manufactures.each do |manufacture| %>
<%= manufacture.id %>
<%= manufacture.name %>
<% end %>
Does this work?
Also this might work, if the manufacturers are being found by Manufacture.search params[:q]
<%= #manufactures.find(car.manufacture_id).name %>
or if they are not
<%= Manufacture.find(car.manufacture_id).name %>

If two DateTime stamps are the same in Rails

I have created a simple appointment system, and I now need to display something inside a loop if there's two or more appointments with the same date and time. The appointments are displayed in order of time, so they're just appearing one after the other.
Controller
def index
#todays_apps = current_user.appointments.order(time ASC)
end
View
<% #todays_apps.each do |app| %>
<%= app.business_name %>
<%= app.business_address %>
<%= app.time %>
<% end %>
I'm looking to display a message or icon the appointment shares a date and time with another appointment. Tried a collection of things with no luck.
You can group your collection by time and modify your iteration accordingly. You can group it like
#todays_apps.group_by(&:time)
The outcome will be something like
=> { timestamp1 => [app1,app2], timestamp2 => [app3], timestamp3 => [app4]}
Or you can try a quick hacky way like:
<% previous_time = nil %>
<% #todays_apps.each do |app| %>
<%= app.business_name %>
<%= app.business_address %>
<%= 'Your message or class or anything' if previous_time == app.time %>
<%= previous_time = app.time %>
<% end %>
Try Like this:
controller:
def index
#appointments = current_user.appointments.order("time ASC")
#todays_apps = #appointments.group_by(&:time)
end
View:
<% #todays_apps.each do |time, appointments| %>
<%= time %>
<% appointments.each do |appointment| %>
<%= appointment.business_name %>
<%= appointment.business_address %>
<% end %>
<% end %>
It will list all the appointments for particular time.
Thanks

Rails 3 group_by associated model

I've been trying to group models in index by an associated model.
Here's what i have:
I have model location.rb
belongs_to :continent
which belongs to Continent.rb
has_many :locations
locations_controller.rb
def index
#locations = Location.find(:all)
end
and on my Index page
<% #locations.group_by(&:continent_id).each do |continent, locations| %>
<li><%= continent %></li>
<% locations.each do |location| %>
<%= location.name %>
<% end %>
<% end %>
I want to group locations by continent. This code above works, but i just need to show the name of the continent, now it shows only the id nr.
What's the best way to do it ?
I am newbie and I know this must be easy, but I'm a bit stuck.
Thanks.
First, it seems to me you're listing the continents, not the locations (to keep it restfull). So I would change that for the continents controller. In the continents controller:
def index
#continents = Continent.find(:all)
end
In continents/index.html.erb:
<% #continents.each do |continent| %>
<li><%= continent.name %></li>
<% continent.locations.each do |location| %>
<%= location.name %>
<% end %>
<% end %>

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

Rails: two attributes diffrent tables in view

I have been trying trying to use two attributes from two different models so they can be used with the calendar_for method provided by the table_builder plugin in the index view. I have been through the Rails guides for http://guides.rubyonrails.org/active_record_querying.html#retrieving-multiple-objects and posts such as Ruby on Rails: How to join two tables however i must be doing something wrong.
My models are as follows:
Class Event < ActiveRecord::Base
belongs_to :user
and
class User < ActiveRecord::Base
User has_many :events
The different ways I have tried in the controller (not all at once) are:
#event.user.name
#users = User.joins(:event).where(:event => {:event_date => true})
#users = User.where(:event => :event_date)
Amoung others, my view looks like:
my view code:
<% calendar_for #users, :year => #date.year, :month => #date.month do |calendar| %>
<%= calendar.head('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday') %>
<% calendar.day(:day_method => :created_at) do |date, users| %>
<%= date.day %>
<ul>
<% for user in users %>
<li><%= link_to h(user.name), user %></li>
<% end %>
</ul>
<% end %>
<% end %>
</div>
I have tried changing the variables in the view accordingly however to no avail. I would like to show the users name and a link to the user on the specific day that their event is booked.
Two issues I see, though I'm not familiar with the calendar library.
First, make sure your query in the controller returns something useful. Of the three lines you gave us, the first doesn't even search, it calls methods on an undefined variable. The second is close to working, but you are searching for a date and matching it to true... How about:
#users = User.joins(:event).where('events.event_date is not null')
Furthermore, if you have a date range, you might include that in the search:
#users = User.joins(:event).where('events.event_date > ? and events.event_date < ?', start_date, end_date)
Next in the view, you aren't consistent with your variable naming. The controller sets up the #users variable, which you access once, but then later you are missing the # in front of it, which is not the same thing. I don't know what the calendar part wants as input, but at least the for loop should be:
for user in #users
That said, for loops are not very rubyish. The ruby way is to use each:
#users.each do |user|
...
end
or even better, to make all of your links:
<ul>
<%= #users.collect {|user| content_tag(:li, link_to h(user.name), user).join } %>
</ul>
edit
Based on more information, I think you are starting at the wrong place. Let's start with events.
Event.joins(:users).where('events.event_date is not null')
<% calendar_for #events, :year => #date.year, :month => #date.month do |calendar| %>
<%= calendar.head('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday') %>
<% calendar.day(:day_method => :event_date) do |date, events| %>
<%= date.day %>
<ul>
<% for event in events %>
<li><%= link_to h(event.user.name), event.user %></li>
<% end %>
</ul>
<% end %>
<% end %>

Resources