how to check whether association exists rails - ruby-on-rails

I have two tables
Post
Category
I have the following code in my controller:
#category = Category.find(id)
Suppose consider category as mobile, car, bike
I need to check the existence of mobile or car or bike. So that I can disable the input element. I tried:
<% #category.each do |cat| %>
<% if cat.posts.exists %>
class = 'active'
<% else %>
class = 'inactive'
<% end %>
<div class="#{class}"><%= cat.name %></div>
<% end %>
The above code always runs the else condition.
Following are the categories:
Mobile
Car
Bike
If in my post table with column category_id has the field with value 1 then mobile should have a class active and the other two should be inactive.

I think you are looking for the any? method:
<% #category.each do |cat| %>
<div class="#{cat.posts.any? ? 'active' : 'inactive'}"><%= cat.name %></div>
<% end %>

Related

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

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 :)

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

For the first x in array?

I imagine this has a rather simple answer
<% for user in #users %>
<li>
<%= link_to user.username, user %>
</li>
<% end %>
Taking my simple example above, how would I apply a class to my <li> to the first three instances returned?
Secondly, how could I just have the the second two items have a different class from the first one? as in 1..2
Either you could count manually (which is kinda ugly):
<% i = 0 %>
<% for user in #users %>
<li class=<%= (i < 3 ? "foo" : "bar") %>>
<%= link_to user.username, user %>
</li>
<% i = i.next %>
<% end %>
or use each_with_index
<% #users.each_with_index do |user, i| %>
<li class=<%= (i < 3 ? "foo" : "bar") %>>
<%= link_to user.username, user %>
</li>
<% end %>
Once you get to more complex things than i < 3 (like your 1..2 issue) you should think about a helper_method (in helpers) like class_by_position(pos) so that you can write
<li class=<%= class_by_position(i) %>>
The :first-child pseudoselector might be a better way to go, but you'll need to have a counter variable that keeps track of the iterations to do it your way.
Your question is a little vague. I can't tell if you want to stop processing the array after the first x, or not.
If you're just looking to stop after the first x items, or just looking for the 2nd and 3rd items the solution is to use a slice.
Example: just the first 3:
#user[0,3].each do |user|
... # only executed for user = #user[0],user = #user[1] and user = #user[3]
end
Example: just the second and third:
#user[1,2].each do |user|
... #only only executed for user = #user[1] and user = #user[3]
end
And here's a more specific answer to your question using these new concepts and the content_tag to programatically decide the class of the list item. If you're going to be doing this often, makes a great candidate for a function.
<% first = true %>
<% #user[0,2].each do |user| %>
<% content_tag :li,
:class => first ? "class-for-first-item" : "class-for-2nd-&-3rd" do %>
<%= link_to user.username, user %>
<% end %>
<% first = false %>
<% end %>
<!-- Now to do the rest of them:-->
<% #user[3,-1].each do |user| %>
<% content_tag :li, :class => "class-for-rest" do %>
<%= link_to user.username, user %>
<% end %>
<% end %>

Resources