Time format while submitting - ruby-on-rails-3

I have a form input code like this:
<%= f.time_select :delivery_time, {:default => 5.hours.from_now, :minute_step => 5, :ampm => true}, {:class=>"input-small"} %>
This is submitting value like: 2013-04-09 23:00:00 UTC
But i want value like : 23:00 as need define condition on time irrespective of date. I tried doing something like:
if (#order.delivery_time.between?('21:00', '00:00'))
#order.total = #order.total + ##mnc
end
But It gives error as delivery_time is nil:class. But when print delivery_time it prints : 2013-04-09 23:00:00 UTC.
Not getting how to get it work. Can anyone help?

You could probably conjure some date values so that you could call #between?. It would be simpler and more intention-revealing to extract just the part of the date you need to compare.
def late_order?(time)
time.hour > 21
end
delivery_time = Time.new(2012, 1, 1, 22)
total = 300
total += 75 if late_order?(delivery_time)
puts "total for order: #{total}" #=> 375

Related

rails params[:month] stripping leading zeros causing incorrect match

In my application when a user visits finances/trends/2014/03 a select query is executed in my trends_controller
#expenses = Expense.select("name, amount, id, created_at").where(:user_id => current_user.id).where(["strftime('%Y', created_at) = ? AND strftime('%m', created_at) = ?", params[:year], params[:month] ])
#expenses_by_month = #expenses.group_by { |expense| expense.created_at.beginning_of_month }
and if the query returns results, the page is rendered, otherwise a redirect occurs. This all seems to work fine.
The problem occurs when I attempt to pass the params[:month] into a link on my index page, and the leading zero in the :month seems to get stripped, so the link will return a path such as finances/trends/2014/3 instead of the required finances/trends/2014/03 for the select statement (because in the db, the created_at value is stored as 2014-03-day, of course).
routes:
get "finances/trends/:year/:month" => "trends#month", :as => :month_trends
index.html.erb:
<% #expenses_by_month.each do |month, expenses| %>
<%= link_to "#{month.strftime('%B')}", month_trends_path(:year => month.year, :month => month.month) %>
<% end %>
I understand that the %m in the select statement should return the month as a padded value, so I'm not sure at all what is causing this.
Try some direct ruby way, if that works. Here is how
"3".rjust(2,"0") #=> 03
"3".ljust(2,"0") #=> 30
month=3
month.to_s.rjust(2,"0") #=> 03

display subseconds in time_select in Rails form

I have a form to record sports times : I need minutes, seconds and hundredths of second, i.e. 1:31.43 --- I don't need the hour.
In my form I use :
<%= f.time_select :perf_time, {:discard_hour => true, :default => {:minute => '00', :second => '00'}, :include_seconds => true} %>
This displays 2 select pull-downs, one for minutes and one for seconds.
I have added a separate field for hundredths of second (type Integer):
<%= f.number_field :perf_time_cents, :in => 0..999 %>
Now I'd like to use the method .change()in my helper to change add/change the microseconds to perf_time. Here's my code, but it does not do anything.
before_save :set_perf_time
def set_perf_time
self.perf_time.change(usec: (self.perf_time_cents * 10))
end
There is no option for milliseconds in time_select because a combobox with 1000 possible values would not be user friendly.
You could use instead a separate text field for the number of milliseconds, with the HTML5 type number:
<%= f.number_field :perf_time_millis, :in => 0..999 %>
In the controller, use both the values in the selects and the text input field to get the full time in millis:
time_in_millis = params[:perf_time_millis].to_i + 1000 * (params["perf_time(5i)"].to_i * 60 + params["perf_time(6i)"].to_i))

How to list all times from 20:00 untill 24:00 in a collection and only list the times > Time.now

Im trying to populate a collection with Times like 20.00, 20.10, 20.20 ... 24:00. So in intervals of 10.minutes. But how to do this smartly and take into account the Time.now?
Only times that are > Time.now should be listed.
So if its 20.30 It should not show 20.10, 20.20,20.30
Example code
= f.input :order, :collection => ["20:00","20:10","20:20"... etc ["24:00"],
:default => 2,
:label => "orders,
:hint => "Select the time you want this order to be processed"
Some of the things Ive tried so far:
:collection => [(Time.now + 10.minutes).strftime("%I:%M%p").to_s]
and
#hours=(Time.now.minus_with_coercion(Time.now.midnight)/3600/2)
Any thoughts how to cleanly code this ? Thank you
Not sure to understand your problem but this could help :
Time.parse('20:00').to_datetime.step(Time.parse('23:59'), 10.minutes).to_a.map {|date| date.strftime("%I:%M%p")}
=> ["08:00PM", "08:10PM", "08:20PM", "08:30PM", "08:40PM", "08:50PM", "09:00PM", "09:10PM", "09:20PM", "09:30PM", "09:40PM", "09:50PM", "10:00PM", "10:10PM", "10:20PM", "10:30PM", "10:40PM", "10:50PM", "11:00PM", "11:10PM", "11:20PM", "11:30PM", "11:40PM", "11:50PM"]
After that, you could call the delete_if method to remove unwanted time.
Something like that :
Time.parse('20:00').to_datetime.step(Time.parse('23:59'), 10.minutes).to_a.delete_if {|date| date < DateTime.now.to_time}.map {|date| date.strftime("%I:%M%p")}

Rails query question

I got a model called items, with a field called weeks. The content in weeks is as follows:
{2011=>["46", "47", "48", "49"]}
How can i do something like this:
Item.where(:week => week, :year => year)
When just passing one week example: 47 and year 2011
Thanks.
# Model
class Item < AR::Base
def self.with_week(weeek)
where("week LIKE (?)", "\"#{week}\"")
end
def self.with_year(year)
where("week LIKE (?)", "{#{year}=>")
end
end
usage
#items = Item.with_week(47).with_year(2011)

How do I search by date in PGSQL?

I am getting this error:
ActionView::Template::Error (PGError: ERROR: operator does not exist: timestamp without time zone ~~ unknown LINE 1: ... "articles" WHERE ("articles"."created_at" LIKE '2010...
I have an archive controller where I can dynamically display articles by genre and year, month and day, with whichever of those fields are available in the url. In mysqlite, I had this index action:
def index
filter_title
#articles = Article.where(:created_at.matches % date_builder, :genre.matches % genre_builder).order("created_at DESC")
respond_to do |format|
format.json { render :json => #articles }
format.xml { render :xml => #articles }
format.html
end
end
And this date_builder function
def date_builder
#date = ""
#date += params[:year] if !(params[:year].nil?)
#date += "-" + params[:month] if !(params[:month].nil?)
#date += "-" + params[:day] if !(params[:day].nil?)
#date += "%"
#date
end
that would use metawhere to find dates that matched the part of the string that I supplied. This worked perfectly in Sqlite. I have migrated my application onto heroku and PGSQL, and it doesn't allow me to do this. What is the solution? Thank you!
In postgres, a timestamp is not stored as a string like in sqllite:
select 'A' where localtimestamp like '2011-04-04%';
ERROR: operator does not exist: timestamp without time zone ~~ unknown
how about using >= instead?
select 'A' where localtimestamp >= '2011-04-04';
?column?
----------
A
(1 row)
While I liked #JackPDouglas answer, I wanted to try and keep sql code out of my project as much as possible, so i ended up doing this:
...
date_builder
if !(params[:year].nil?)
#articles = Article.where(
{:created_at.gt => #datelower} &
{:created_at.lt => (#datehigher - 1.second)} &
:genre.matches % genre_builder
).order("created_at DESC")
else
...
and this method for the date:
def date_builder
if !(params[:day].nil?)
#datelower = Time.utc(params[:year], params[:month], params[:day])
#datehigher = #datelower + 1.day
elsif !(params[:month].nil?)
#datelower = Time.utc(params[:year], params[:month], 01)
#datehigher = #datelower + 1.month
elsif !(params[:year].nil?)
#datelower = Time.utc(params[:year], 01, 01)
#datehigher = #datelower + 1.year
end
end