How to render only notes that equal date? - ruby-on-rails

Instead of showing all the notes per day, how can we only show one note per day, the note whose note.note_date == date?
Day 1: Notes/notes # Shows both Day 1 and Day 3 note. Only want to show Day 1 note
Day 2: Notes/form
Day 3: Notes/notes # Shows both Day 1 and Day 3 note. Only want to show Day 3 note
Day 4: Notes/form
Day 5: Notes/form
challenges/show
<% #challenge.dates_challenged.first(#challenge.days_challenged).each_with_index do |date, i| %>
Day <%= i + 1 %>
<% if #notes.any? { |note| note.notes_date.strftime("%m/%d/%y") == date.strftime("%m/%d/%y") } %>
<%= render 'notes/notes' %>
<% else %>
<%= render 'notes/form', :date => date %>
<% end %>
<% end %>
notes/notes
<% #notes.each do |note| %>
<%= note.notes_text %>
<% end %>
notes/form
<%= form_for [#notable, #note] do |f| %>
<%= f.text_area :notes_text, placeholder: 'Enter Recap' %>
<%= f.date_select :notes_date, selected: date, :order => [:month, :day, :year] %>
<% end %>
challenges_controller
def show
#notable = #challenge
#notes = #notable.notes
#note = Note.new
end
To recap, a user creates a challenge. A challenge has the attribute days_challenged. The user chooses how many days will be challenged, i.e. 10, 15, 30, etc. For each of those days a notes/form will be rendered. If a note.notes_date equals a respective day then how can we only show that one note in place of notes/form?

<% if #notes.any?
#today_notes = #notes.select{ |note| note.notes_date.strftime("%m/%d/%y") == date.strftime("%m/%d/%y") } %>
<%= render 'notes/notes' %>
<% else %>
...
<% end %>
Then use #today_notes in the notes/notes partial.

Change this <%= render 'notes/notes' %> partial to below one, and follow right below note.html.erb file.
Challenges Show:
<%= render partial: 'notes/notes', locals:{note: note} %>
Rename note.html.erb to underscore _notes.html.erb
notes/_notes.html.erb:
<%= note.notes_text %>

Related

RoR iterate through a group/each_slice

I'm looking to get the last 5 items in an array, but to display each item individually, not as a group.
Here's what I've tried below with no success.
#array = Town.all
<% #array.each_slice(5) do |a| %>
<%= a.first %>
<%= a.second %>
<%= a.third %>
<%= a.fourth %>
<%= a.fifth %>
<% end %>
I can't figure out how to pull out a specific number of items and then to call each individual item.
The method you are looking for is in_groups_of (https://apidock.com/rails/Array/in_groups_of):
<% #towns.in_groups_of(5) do |five_towns| %>
<% five_towns.each do |town| %>
# [...]
<% end %>
<% end %>
Update: Maybe you want only the last 5 elements of the array. If so, you can simply call:
Town.all.last(5)
# => array of (max) 5 Town records
To get the last 5 items of an Array you could use last and then iterate them with each:
<%= #array.last(5).each do |a| %>
...
<% end %>
But it seems that you want to get the last 5 records of a model; in that case, you could try this instead:
#array = Town.limit(5).order('id desc')
<%= #array.each do |a| %>
...
<% end %>
... is there a way that I can have let's say the last 5 records of a
model all within one loop? maybe
<%= #array.each do | a, b, c, d, e| %>
<%= a.description %>
<%= b.description %>
<% end %>
You could use the index of each item instead of using each; for example:
#last_five = #array.last(5)
<%= last_five[0] %>
<%= last_five[1] %>
<%= last_five[2] %>
<%= last_five[3] %>
<%= last_five[4] %>
Although that wouldn't be DRY, so it will be better to stick with each.

How to group_by different attributes?

I'm trying to create a timeline for #challenges. For those challenges that have a :deadline I want them to be organized on the timeline according to their :deadline and for those challenge that have a :date_started I want them to be organized on the timeline according to their :date_started.
If a challenge has a :deadline then date_started is nil and vice versa.
example
2016
February
CHALLENGE 1 (Deadline: 1st)
CHALLENGE 2 (Date_Started: 3rd)
CHALLENGE 3 (Deadline: 18th)
controller
#challenges = current_user.challenges
#challenges_timeline = #challenges.group_by { |t| t.deadline.beginning_of_year + t.date_started.beginning_of_year }
view
<% #challenges_timeline.sort.each do |year, challenges| %>
<%= year.strftime('%Y') %>
<% challenges.group_by { |t| t.deadline.beginning_of_month + t.date_started.beginning_of_month }.sort.each do |month, challenges| %>
<%= month.strftime('%B') %>
<% for challenge in challenges %>
<% if challenge.deadline.present? %>
<%= challenge.deadline %>: <%= challenge.action %>
<% end %>
<% if challenge.date_started.present? %>
<%= challenge.date_started %>: <%= challenge.action %>
<% end %>
<% end %>
<% end %>
<% end %>
Change your schema:
If the two dates negate each other, perhaps you should have just one date field, and another field to show whether the date is the beginning or the end. That would allow you to group on the database level, saving some processing time.
Add instance method
A simple instance method such as
def timeline_date
deadline || date_started
end
would allow simple grouping such as
challenges.group_by { |c| c.timeline_date.beginning_of_month }
Use || directly in the group_by block.

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

Order by time_field

I have a database table called "bookings" which users can select the 'time_from' and 'time_to' in which they want the booking done.
When adding these fields to the database I added them as a time_field.
<%= f.label :time_from, "From (24hr Clock)" %>
<%= f.time_field :time_from %>
<%= f.label :time_to, "To (24hr Clock)" %>
<%= f.time_field :time_to %>
The form works and saves correctly but my problem is the order. Below is my controller code and subsequently my view to display the time and its output. Any idea on how to order these by time correctly?
Controller:
def show
#location = Location.find(params[:id])
#booking = Booking.order("time_to")
#company = Company.all
end
View:
<% 0.upto(11.to_i).each do |day_count| %>
<span class="col-md-3 booking-times">
<h4><%= time_tag(Date.today + day_count.days) %></h4>
<span class="label label-danger no-bookings">No Bookings</span>
<% #booking.each do |b| %>
<% if b.date == Date.today + day_count.days && b.type == "Meeting" %>
<% if b.location == params[:id] %>
<span class="label label-info booking-time">
<%= time_tag(b.time_from, :format=>"%H:%M") %> -
<%= time_tag(b.time_to, :format=>"%H:%M") %>
</span>
<% #company.each do |c| %>
<% if c.id == b.company %>
<%=link_to c.name, c %></br>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
</span>
<% end %>
Output: (For first day time)
09:30 - 10:30
22:00 - 23:00
07:30 - 08:30
I appreciate this is not the nicest looking code. I would like the above output to order by time. Any ideas? I have tried to order in the controller, this effects the layout but not in the correct order still. I think the dat attatched to the time_to input may be having ian affect? Thanks!
Have you tried this:
#booking = Booking.order(time_to: :desc)
Can you please try this:
#booking = Booking.order('time_to desc')

Ruby on rails forms, partial

I have index page:
<div>
<%= render :partial => "ev_calendar" %>
</div>
<% Project.events.each do |event| %>
<%= link_to l(event.published_at, :format => "%d.%m.%Y"), event %>
<div>
<%= event.description %>
</div>
<% end %>
ev_calendar:
...
<%= day %>
...
day - it's a day oncalendar, only a number. How can I make this da like link, after clicking on this link - my page reloaded and first example-code show events only for this day (by created_at attribute).? plz help me
You can do this:
<%= link_to day, your_path_to_action(:day => day) %>
then you can catch :day parameter in params[:day]. In action you can verify this parameter and do something like this:
Project.events.where(["DAY(created_at) = ?", params[:day]])

Resources