trouble making an "if" statment with time.now on ruby on rails - ruby-on-rails

I'm trying to display a message depending on the time of the day and I currently have this piece of code:
<% if Time.now >= "7:00" and Time.now <= "14:00" %>
Good Morning <%= current_user.nome %>! <br>
<% else %>
Good Afternoon <%= current_user.nome %>!
<% end %>
It's currently 14:30 and the page still displays Good Morning (username), when it should display Good Evening (username)
Is my code wrong?
How do I fix this?

try:
<% if Time.now >= Time.parse("7:00") and Time.now <= Time.parse("14:00") %>
Good Morning <%= current_user.nome %>! <br>
<% else %>
Good Afternoon <%= current_user.nome %>!
<% end %>
Note: Time.now will return time object while "7:00" is a string, so you need to convert string time to time object and can compare.

You can write like this Instead of Parsing the Time you can write simply
Solution : 1
<% if Time.now.hour >= 7 && Time.now.hour <= 14 %>
Good Morning <%= current_user.nome %>! <br>
<% else %>
Good Afternoon <%= current_user.nome %>!
<% end %>
Solution : 2
you can write less code via using ternary operator
(0..11).include?(Time.now.hour) ? "Good Morning <%= current_user.nome %>" : Good Afternoon <%= current_user.nome %>

I think this is worth it to be a helper method:
# in app/helpers/application_helper.rb
def greeting(name)
greeting = (7..13).cover?(Time.current.hour) ? 'Good Morning' : 'Good Afternoon'
"#{greeting} #{name}".strip
end
And in your view:
<%= greeting(current_user.nome) %>!
Another more detailed version that supports uneven times might look like this:
def greeting(name)
greeting = case Time.current.to_s(:time)
when ('05:00'..'11:59') then 'Good Morning'
when ('12:00'..'17:59') then 'Good Afternoon'
when ('18:00'..'21:59') then 'Good Evening'
else 'Good Night'
end
"#{greeting} #{name}".strip
end

I would use helpers to store methods and keep views plain.
class ApplicationHelper
def greeting
"Good #{time_greeting} #{current_user.nome}"
end
def time_greeting
return "Morning" if Time.now.hour.between?(7, 13)
"Afternoon"
end
end
Then you may only use greeting method in your views:
<%= greeting %>

I'd use a helper:
def morning?(t = Time.current)
t.between? t.change(hour: 7), t.change(hour: 14)
end
t is a time instance, defaulting to the current time, for example:
t = Time.current
#=> Tue, 04 Jul 2017 16:30:09 CEST +02:00
change sets one or more of the time's elements. If only :hour is specified, the "smaller" units like minutes and seconds are set to 0:
t.change(hour: 7) #=> Tue, 04 Jul 2017 07:00:00 CEST +02:00
t.change(hour: 14) #=> Tue, 04 Jul 2017 14:00:00 CEST +02:00
between? finally checks if t is between these values.
Passing the current time as an argument makes it easier to test the method:
morning? Time.parse('06:59') #=> false
morning? Time.parse('07:00') #=> true
morning? Time.parse('14:00') #=> true
morning? Time.parse('14:01') #=> false
Usage:
<% if morning? %>
Good Morning <%= current_user.nome %>!
<% else %>
Good Afternoon <%= current_user.nome %>!
<% end %>

Related

How to sort group_by month and year in view?

pages_controller.rb
#past_challenges_by_years = #past_challenges.group_by { |t| [t.deadline.year, t.deadline.month] }
How can I break it down in the view with year and then subdivide it with month like this:
2014 # Years
01 # Months
Challenge
Challenge
02
Challenge
08
Challenge
2016
03
Challenge
08
Challenge
view.html.erb
<% #past_challenges_by_years.sort.each do |year, challenges| %>
<%= year %>
<%= month %> # I don't know how to define this.
<% for challenge in challenges %>
etc...
<% end %>
<% end %>
I would start by sorting the keys and then look up the challenges while iterating through those keys.
<% #past_challenges_by_years.keys.sort.each do |(year, month)| %>
<%= year %>
<br />
<%= month %>
<br />
<% #past_challenges_by_years[[year, month]].each do |challenge| %>
<%= challenge %>
<br />
Edit: Here is a new solution that only displays years and months once.
#past_challenges_by_years.keys.map { |a| a[0] }.uniq.sort.each do |year|
puts year
#past_challenges_by_years.keys.select { |a| a[0] == year }.map { |a| a[1] }.uniq.sort.each do |month|
puts month
#past_challenges_by_years[[year, month]].each do |challenge|
puts challenge
end
end
end
I think it should be simple enough to convert to ERB.

Compare date_time with today's date

I’m trying to compare a saved date_field with today’s date. Seems to work in console but I can't make it work in my code.
<% #flights.each do |flight| %>
<% if (Time.new("%Y-%m-%d") < flight.flight_date) %>
<tr class="active">
<% else %>
<tr class="success">
<% end %>
Thanks to #drenmi for the patient answers and explaining why that my date_field was saved as a datetime attribute hence Time.now working and not Date.today.
Now to fix my naming so I follow convention!
Using Time.new("%Y-%m-%d") will produce an empty Time object:
Time.new("%Y-%m-%d")
# => 0000-01-01 00:00:00 +0730
What you want to do is compare to Time.now:
<% if Time.now < flight.flight_date %>
Or, if using Rails, you might want to use Time.current, or Date.current:
<% if Date.current < flight.flight_date %>
or
<% if Time.current < flight.flight_date %>
you want using Date.today in rails
Time.now.utc
this is the best choice
time = Time.now.utc.iso8601
Time.iso8601(time)
...
don't forget: require 'time'

Ruby on Rails: How to get the current week and loop through it to display its days?

The above picture is what I mean.
I think the code should be something like:
<% #days_from_this_week.each do |day| %>
<%= day.name %>
<!--e.g. Monday-->
<% day.sessions do |session| %>
<% #session_categories.each do |category| %>
<!--categories means the Sesion1/2/3/4 category
A day's sessionX could be empty, so we have to determine wheather a session matches its cateogry,
and then display it in the table
-->
<% if session.category == category %>
<%= session.content %>
<% end %>
<% end %>
<% end %>
<% end %>
But how to get the current week? And how to get the name of a day? And to navigate through this calendar, pre_week and next_week is also needed.
I foundprev_week and next_week method, but it seems like return a certain day after a week, which is not I need.
A possible solution is here, but I don't know how to use it.
UPDATE:
I found a workable solution, but still looking for better code:
<!-- #date = params[:date] ? Date.parse(params[:date]) : Date.today
first=#date.at_beginning_of_week
last=#date.at_beginning_of_week + 6
#days= (first..last).to_a-->
<% #days.each do |day| %>
<div>
<%= day %>
</div>
<% end %>
Try this in your controller where you're setting the #days_from_this_week
today = Date.today # Today's date
#days_from_this_week = (today.at_beginning_of_week..today.at_end_of_week).map
To show what this does:
> (today.at_beginning_of_week..today.at_end_of_week).map.each { |day| day }
> [Mon, 12 Aug 2013, Tue, 13 Aug 2013, Wed, 14 Aug 2013, Thu, 15 Aug 2013, Fri, 16 Aug 2013, Sat, 17 Aug 2013, Sun, 18 Aug 2013]
Update to additional request of querying articles by published on:
Find all the articles between start date's midnight to next day.
start_time = Time.parse(date.to_s)
end_time = 1.day.since(start_time)
Article.where('published_on >= ? and published_on < ?', start_time, end_time)
The solution is here
A method for the current week would be something like:
def current_week
date = Date.today.beginning_of_week
return (date..date + 6.days).to_a
end
Then when you have the day array, you can use strftime to format the dates
day.strftime("%A") # prints weekday name

How do I split the value returned by created_at?

I am trying to split the value returned by the created_at method.
I am taking an object (item) and getting the time it was created at. I don't want the whole result and I am only interested in the day, month and year. How can I get this to work?
<% #items_in_basket.each do |item| %>
<% splliter = item.created_at.split(" ") %>
<% time = #splliter[0] %>
I get this as a result:
undefined method 'split' for Wed, 31 Jul 2013 16:44:37 UTC +00:00:Time
created_at returns an instance of ActiveSupport::TimeWithZone which you can simply call day, month, or year on to get those parts of the date. Example:
<% #items_in_basket.each do |item| %>
Day: <%= item.created_at.day %>
Month: <%= item.created_at.month %>
Year: <%= item.created_at.year %>
<% end %>
This approach will be much more reliable than parsing the string format returned by to_s.
Try converting the date to string first before using the string method split (http://ruby-doc.org/core-2.0/String.html#method-i-split).
<% splliter = item.created_at.to_s.split(" ") %>
The reason you are getting that error is because Time (http://www.ruby-doc.org/core-2.0/Time.html) class does not have split method.

Rails hash and arrays

I am making a timesheet, but i have problems.
I want it to look like this:
projects |Monday Tuesday Wednesday Thursday Friday Saturday Sunday
development| 3:50 4:00 5:00 3:00 0:00 0:00 0:00
Testing | 0:00 0:00 0:00 2:00 4:00 0:00 0:00
Lanch | 0:00 0:00 0:00 0:00 1:00 6:00 0:00
Every project has_many logs with hours as a field.
I did this query:
#log_week_project = current_user.logs.where(:log_date => (Time.now.beginning_of_week + 1.second)..(Time.now.end_of_week - 1.second)).group("project_id").group("date(log_date)").sum(:hours)
And get this:
<OrderedHash {[2, "2011-05-24"]=>31800.0, [1, "2011-05-24"]=>10200.0, [1, "2011-05-23"]=>25200.0, [1, "2011-05-26"]=>19800.0}>
The key in the hash is an array with the project_id # [0] and log_date # [1]. The value is the hours.
I do this in my view:
<% for project in #projects do %>
<%= project.name %>
<% #log_week_project.map do |key,hours|%>
<% if key[0] == project.id %>
<%= time_diff(hours)%>
<% end %>
<% end %>
<% end %>
This gives me the project hours on each date, but if there is a date with no hours there is no output and the table gets wrong.
If there is no hours on wednesday the thursday hours ends up in the wednesday column.
Any tips on how to do this? Perhaps there is a better way?
SOLUTION:
Thanks for replies and comments. The solution was:
<% for project in #projects do %>
<%= project.name %>
<% #dates.each do |date| %>
<% hours = #log_week_project.detect { |key| key[0][0].to_i == project.id && key[0][1].to_time.strftime('%a') == date.to_time.strftime('%a')}%>
<%= hours ? time_diff(hours[1]) : "0:00"%>
<% end %>
<% end %>
Where #dates is an array of the dates in the timerange. Now refactoring... ; )
you can do this:
<% for project in #projects do %>
<%= project.name %>
<% (1..7).each do |day| %>
<% date = "2011-05-#{22 + day}" #please modify this, this is only to keep the example simple %>
<% hours = #log_week_project.detect{|key| key[0] == project && key[1] == date } %>
"<%= hours ? time_diff(hours) : "" %>
<% end %>
<% end %>
<% end %>
<% end %>
next, refactor this to put all the logic in a helper.
Hope, that helps
In your database you may have 0 as default for all hours, that way it can't be blank.
But if you storing hours in logs, then you can't do above. In that case, use
time_diff(hours).present? ? time_diff(hours) : 0
Or else you may use anything else than 0, that way tables will not disturbed.

Resources