Why my DateTime format changed on Bamboo build - ruby-on-rails

I have a User class that has_many Jobs. I map jobs with the following code, the start_at and end_at are datetime:
def ranges
user.jobs.map { |u| [u.start_at, u.end_at] }
end
I have a spec that compares two arrays:
my_array = [[start1, end1], [start2, end2]]
expect(ranges).to eq my_array
The test data are also datetime created from factory girl e.g.
create(:jobs, start_at:DateTime.parse('2017-03-26 00:00:00'), end_at: DateTime.parse('2017-03-27 00:00:00'))
Everything works fine, expect when Bamboo runs my spec, I get following error:
expect
[[2017-12-31 00:00:00.000000000 +0000, 2017-12-31 10:10:00.000000000 +0000], [2017-12-30 00:00:00.000000000 +0000, 2017-12-31 00:10:00.000000000 +0000], [2017-11-26 00:00:00.000000000 +0000, 2017-11-26 10:10:00.000000000 +0000], [2017-03-24 00:00:00.000000000 +0000, 2017-03-24 10:10:00.000000000 +0000], [2017-03-25 00:00:00.000000000 +0000, 2017-03-25 10:10:00.000000000 +0000], [2017-03-26 00:00:00.000000000 +0000, 2017-03-26 10:10:00.000000000 +0000]]
to match
[[Sun, 26 Mar 2017 00:00:00 UTC +00:00, Sun, 26 Mar 2017 10:10:00 UTC +00:00], [Sat, 25 Mar 2017 00:00:00 UTC +00:00, Sat, 25 Mar 2017 10:10:00 UTC +00:00], [Fri, 24 Mar 2017 00:00:00 UTC +00:00, Fri, 24 Mar 2017 10:10:00 UTC +00:00], [Sun, 26 Nov 2017 00:00:00 UTC +00:00, Sun, 26 Nov 2017 10:10:00 UTC +00:00], [Sat, 30 Dec 2017 00:00:00 UTC +00:00, Sun, 31 Dec 2017 00:10:00 UTC +00:00], [Sun, 31 Dec 2017 00:00:00 UTC +00:00, Sun, 31 Dec 2017 10:10:00 UTC +00:00]]
dose this mean I need to format all my datetime object byiso8601 all the time? what could cause this on Bamboo

The problem isn't your format. The problem is that the array elements are not in the same order. The dates in your expect array begin with the 2017-12-31 dates, while those in your match array begin with the 2017-03-26 dates.
RSpec's eq method returns true only if each element of the first array is identical to the element at the same index of the second array. But the match_array method returns true so long as the two arrays have the same elements, regardless of order.
Change your expectation line to:
expect(ranges).to match_array(my_array)
And you should be good to go.

Related

Restrict my website to one per one user without authentification - compare date in array

How can I restrict a page only one by one user without authentification and with a delay of 3min between the first and second user. If anyone have a clue or a solution ?
Here is what I try to do :
A unique User land in my page and fill a form and as I want to pick him by making a User.last I need him to be uniq on my page (to not disturb the registration and to be sure that i'm picking the right user with the User.last) and to wait 3 min for the second user to access this page.
Like I have 10 peoples trying to access my website, 1 in filling the form, the 9 others are standing in a queue and waiting to access to my page.
Actualluy try to do this in Ruby on Rails.
My view with the field looks like this (need to allow only one by one user on this page) :
<div class="container">
<center><h1>New Connection </h1></center>
<%= form_with model: #email, local: true do |form|%>
<% if #email.errors.any? %>
<div id="error explanation" class="alert alert-danger">
<p>Erreur(s) : </p>
<ul>
<% #email.errors.full_messages.each do |message|%>
<li><%=message%></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= label_tag :email %> :
<%= form.email_field :email, placeholder: "Email", class: "form-control" %>
</div>
<div class="form-group">
<%= form.submit class: "btn btn-primary btn-lg btn-block", value: "Se connecter" %>
</div>
<%end%>
</div>
My email controller :
class EmailsController < ApplicationController
def index
redirect_to root_path
end
def new
#email = Email.new
sessions = ActiveRecord::SessionStore::Session.pluck(:updated_at)
#return an array like this :
[Tue, 21 Jan 2020 13:27:03 UTC +00:00, Tue, 21 Jan 2020 13:27:09 UTC +00:00, Tue, 21 Jan 2020 13:27:42 UTC +00:00, Tue, 21 Jan 2020 13:31:33 UTC +00:00, Tue, 21 Jan 2020 13:36:21 UTC +00:00, Tue, 21 Jan 2020 13:42:02 UTC +00:00, Tue, 21 Jan 2020 13:42:02 UTC +00:00, Tue, 21 Jan 2020 13:42:03 UTC +00:00, Tue, 21 Jan 2020 13:42:03 UTC +00:00, Tue, 21 Jan 2020 13:42:04 UTC +00:00, Tue, 21 Jan 2020 13:42:04 UTC +00:00, Tue, 21 Jan 2020 13:44:47 UTC +00:00, Tue, 21 Jan 2020 13:44:47 UTC +00:00, Tue, 21 Jan 2020 13:46:24 UTC +00:00, Tue, 21 Jan 2020 13:49:10 UTC +00:00, Tue, 21 Jan 2020 13:49:38 UTC +00:00, Tue, 21 Jan 2020 13:50:54 UTC +00:00, Tue, 21 Jan 2020 13:50:54 UTC +00:00, Tue, 21 Jan 2020 14:03:42 UTC +00:00, Tue, 21 Jan 2020 14:07:11 UTC +00:00, Tue, 21 Jan 2020 14:07:11 UTC +00:00, Tue, 21 Jan 2020 14:07:12 UTC +00:00, Tue, 21 Jan 2020 14:07:12 UTC +00:00, Tue, 21 Jan 2020 14:36:39 UTC +00:00, Tue, 21 Jan 2020 14:36:48 UTC +00:00, Tue, 21 Jan 2020 14:36:57 UTC +00:00, Tue, 21 Jan 2020 14:42:02 UTC +00:00, Tue, 21 Jan 2020 14:42:03 UTC +00:00, Tue, 21 Jan 2020 14:44:16 UTC +00:00, Tue, 21 Jan 2020 14:52:46 UTC +00:00, Tue, 21 Jan 2020 14:52:47 UTC +00:00, Tue, 21 Jan 2020 14:52:47 UTC +00:00, Tue, 21 Jan 2020 14:54:48 UTC +00:00, Wed, 22 Jan 2020 08:09:47 UTC +00:00, Wed, 22 Jan 2020 08:09:48 UTC +00:00, Wed, 22 Jan 2020 08:12:06 UTC +00:00, Wed, 22 Jan 2020 08:12:07 UTC +00:00, Wed, 22 Jan 2020 08:12:16 UTC +00:00, Wed, 22 Jan 2020 08:12:17 UTC +00:00, Wed, 22 Jan 2020 08:12:17 UTC +00:00, Wed, 22 Jan 2020 08:12:29 UTC +00:00, Wed, 22 Jan 2020 08:12:39 UTC +00:00, Wed, 22 Jan 2020 08:12:40 UTC +00:00, Wed, 22 Jan 2020 08:13:07 UTC +00:00, Wed, 22 Jan 2020 08:13:07 UTC +00:00, Wed, 22 Jan 2020 08:13:08 UTC +00:00, Wed, 22 Jan 2020 08:15:34 UTC +00:00, Wed, 22 Jan 2020 08:22:38 UTC +00:00, Wed, 22 Jan 2020 08:25:28 UTC +00:00, Wed, 22 Jan 2020 08:25:29 UTC +00:00, Wed, 22 Jan 2020 08:25:29 UTC +00:00, Wed, 22 Jan 2020 08:29:24 UTC +00:00, Wed, 22 Jan 2020 08:36:15 UTC +00:00, Wed, 22 Jan 2020 08:36:16 UTC +00:00, Wed, 22 Jan 2020 08:36:16 UTC +00:00, Wed, 22 Jan 2020 08:36:17 UTC +00:00, Wed, 22 Jan 2020 08:36:17 UTC +00:00, Wed, 22 Jan 2020 08:36:18 UTC +00:00, Wed, 22 Jan 2020 08:36:18 UTC +00:00, Wed, 22 Jan 2020 08:36:30 UTC +00:00, Wed, 22 Jan 2020 08:40:30 UTC +00:00, Wed, 22 Jan 2020 08:40:30 UTC +00:00, Wed, 22 Jan 2020 08:41:14 UTC +00:00, Wed, 22 Jan 2020 08:50:25 UTC +00:00, Wed, 22 Jan 2020 08:50:26 UTC +00:00, Wed, 22 Jan 2020 08:50:27 UTC +00:00, Wed, 22 Jan 2020 08:50:37 UTC +00:00, Wed, 22 Jan 2020 08:50:37 UTC +00:00, Wed, 22 Jan 2020 08:50:38 UTC +00:00, Wed, 22 Jan 2020 08:50:48 UTC +00:00, Wed, 22 Jan 2020 08:50:48 UTC +00:00, Wed, 22 Jan 2020 08:50:49 UTC +00:00, Wed, 22 Jan 2020 08:57:58 UTC +00:00, Wed, 22 Jan 2020 08:57:59 UTC +00:00, Wed, 22 Jan 2020 09:04:29 UTC +00:00, Wed, 22 Jan 2020 09:04:29 UTC +00:00, Wed, 22 Jan 2020 09:04:30 UTC +00:00, Wed, 22 Jan 2020 09:04:39 UTC +00:00, Wed, 22 Jan 2020 09:04:39 UTC +00:00, Wed, 22 Jan 2020 09:04:40 UTC +00:00, Wed, 22 Jan 2020 09:04:49 UTC +00:00, Wed, 22 Jan 2020 09:04:49 UTC +00:00, Wed, 22 Jan 2020 09:04:50 UTC +00:00, Wed, 22 Jan 2020 09:13:21 UTC +00:00, Wed, 22 Jan 2020 09:17:48 UTC +00:00, Wed, 22 Jan 2020 09:20:03 UTC +00:00, Wed, 22 Jan 2020 09:27:54 UTC +00:00, Wed, 22 Jan 2020 09:27:54 UTC +00:00, Wed, 22 Jan 2020 09:28:04 UTC +00:00, Wed, 22 Jan 2020 09:28:05 UTC +00:00, Wed, 22 Jan 2020 09:35:42 UTC +00:00, Wed, 22 Jan 2020 09:35:43 UTC +00:00, Wed, 22 Jan 2020 09:35:58 UTC +00:00]
#How can I say that if a session is in the same minute than the previous session, redirect the one last one to another url?
end
def create
#email = Email.create(email_params)
respond_to do |format|
if#email.persisted?
format.html {redirect_to invoice_index_path, notice: 'Email Validated '}
else
format.html{render :new}
end
end
end
private
def email_params
params.require(:email).permit(:email, :id_user)
end
end
EDIT :
As suggested in the comment part, I tried to use the session, I can access to the session made by rails with request.session_options[:id] but how can I count them ?
EDIT 2 :
As suggested by ARK in the comment section, I try to use the Session created by Rails, I edited my controller part .
How can I say that if a session is in the same minute than the previous session, redirect the one last one to another url ?

Ruby on Rails array group sort by value

I've got an array with with arrays, containing a key and a timestamp.
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 22:00:51 CEST +02:00],
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 22:00:32 CEST +02:00],
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 21:58:33 CEST +02:00],
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 21:58:01 CEST +02:00],
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 21:58:51 CEST +02:00],
["3wyadsrrdxtgieyxx_lgka", Sat, 13 May 2017 01:09:01 CEST +02:00],
["y-5he42vlloggjb_whm8jw", Sat, 22 Apr 2017 22:48:31 CEST +02:00],
["oaxej30u9we17onlug4orw", Sun, 23 Apr 2017 01:46:48 CEST +02:00],
["oaxej30u9we17onlug4orw", Sun, 23 Apr 2017 02:06:56 CEST +02:00],
["rqjwg1ka43mvri0dmrdxvg", Sun, 23 Apr 2017 17:23:34 CEST +02:00],
["ok8nq6tg-kor9jglsuhoyw", Tue, 25 Apr 2017 13:02:16 CEST +02:00],
["riwfm0m-0rmbb6e9kyug2g", Sat, 06 May 2017 06:12:27 CEST +02:00],
["riwfm0m-0rmbb6e9kyug2g", Sat, 06 May 2017 06:17:01 CEST +02:00],
["riwfm0m-0rmbb6e9kyug2g", Sat, 06 May 2017 06:18:04 CEST +02:00],
["gbqfn3_d_tritqoey5khjw", Sat, 06 May 2017 14:14:55 CEST +02:00],
["j___x1oap-veh0u1fo_oua", Sun, 07 May 2017 14:22:37 CEST +02:00],
...
I received this list by ActiveRecord.
MyModel.all.pluck(:token, :created_at)
The Model containing some uniq tokens and some duplicates.
The duplicates are interesting.
I want to group the timestaps by the key and look for the first and the last timestamp for each key.
So I grouped the array as following:
grp = arr.group_by { |key, ts| key}
Now I receive a list like this:
"vwfv8n5obwqmaw8r9fj-yq"=>[
["vwfv8n5obwqmaw8r9fj-yq", Thu, 11 May 2017 10:24:42 CEST +02:00]
],
"kacec6ybetpjdzlfgnnxya"=> [
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 22:00:31 CEST +02:00],
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 22:01:43 CEST +02:00],
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 21:58:17 CEST +02:00],
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 21:59:05 CEST +02:00],
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 21:59:59 CEST +02:00]
],
...
Is it possible to sort the dates to get the first and the last date easily?
Am I too complicated? I think there should be an easier way to handle the raw data.
To get a a hash with the token as the key and the timestamps as values:
# this gives the same MIN and MAX if there is only one created_at in the group
rows = MyModel.group(:token)
.pluck("token, MIN(created_at), MAX(created_at)")
# loop though rows and create a hash
rows.each_with_object({}) do |(token, *t), hash|
hash[token] = t.uniq # removes dupes
end
{
"rqjwg1ka43mvri0dmrdxvg"=>[2017-04-23 15:23:34 UTC],
"riwfm0m-0rmbb6e9kyug2g"=>[2017-05-06 04:12:27 UTC, 2017-05-06 04:18:04 UTC]
# ...
}
If you are simply looking for the records which have duplicates you can just use a WHERE clause that counts the records:
MyModel.where("(SELECT COUNT(*) FROM things t WHERE t.token = things.token) > 1")
You could do this:
# you already have this bit
grp = arr.group_by { |key, ts| key}
# get the minmax values for each group
grp.map { |k, values_array| { k => values_array.minmax } }.reduce Hash.new, :merge
This should yield something that looks like:
{
"vwfv8n5obwqmaw8r9fj-yq"=>[
[Thu, 11 May 2017 10:24:42 CEST +02:00, Thu, 11 May 2017 10:24:42 CEST +02:00]
],
"kacec6ybetpjdzlfgnnxya"=> [
[Fri, 12 May 2017 21:58:17 CEST +02:00, Fri, 12 May 2017 22:01:43 CEST +02:00]
],
...
}
try something like this:
MyModel.order(:created_at).pluck(:token, :created_at).group_by { |key, ts| key }.flat_map{ |k, v| { k => [v.first, v.last] } }

Include 'UTC` in datetime

One of my assertions is failing because of this slight niggle:
its(:register_token_created_at){ should eq DateTime.now.utc }
results in:
expected: Fri, 28 Mar 2014 00:06:33 +0000
got: Fri, 28 Mar 2014 00:06:33 UTC +00:00
So how should I change DateTime.now.utc for it to pass?
I'm assuming that you have your test environment with the following configuration:
yourapp/config/environments/test.rb
#config.time_zone = "whatever"
config.active_record.default_timezone = :utc
Then, you can replace:
DateTime.now.utc #Fri, 28 Mar 2014 00:54:28 +0000
With:
Time.zone.now #Fri, 28 Mar 2014 00:54:51 UTC +00:00
That works for me...
Another (ugly) solution can be:
DateTime.now.utc.strftime("%a, %m %b %Y %H:%M:%S UTC %:z") #"Fri, 03 Mar 2014 00:55:46 UTC +00:00"
And then, you can compare as strings

How do get a random DateTime rounded to beginning of hour in Rails?

Basically I'd like to get a random datetime within the last year:
rand(1.year).ago #=> Sun, 22 Sep 2013 18:37:44 UTC +00:00 (example)
But how do I go about specifying or limiting this to times on the hour? For example:
Sun, 22 Sep 2013 18:00:00 UTC +00:00
Sat, 02 Nov 2013 10:00:00 UTC +00:00
Fri, 12 Apr 2013 21:00:00 UTC +00:00
I finally found what I was looking for. #Stoic's answer is very good but I found this available method (http://api.rubyonrails.org/classes/DateTime.html):
rand(1.year).ago.beginning_of_hour
Does exactly the same thing but looks neater and prevents you from having to write your own function.
Rounding datetime to the nearest hour in Rails would be
(DateTime.now + 30.minutes).beginning_of_hour
Not the answer to the actual question, but it does answer the title of the question (which is how i got here).
Try this:
def random_time_to_nearest_hour
time = rand(1.year).ago
time - time.sec - 60 * time.min
end
Examples:
[1] pry(main)> random_time_to_nearest_hour
=> Sun, 28 Apr 2013 16:00:00 UTC +00:00
[2] pry(main)> random_time_to_nearest_hour
=> Sat, 08 Jun 2013 15:00:00 UTC +00:00
[3] pry(main)> random_time_to_nearest_hour
=> Thu, 22 Aug 2013 23:00:00 UTC +00:00
[4] pry(main)> random_time_to_nearest_hour
=> Tue, 29 Jan 2013 14:00:00 UTC +00:00
[5] pry(main)> random_time_to_nearest_hour
=> Tue, 13 Aug 2013 06:00:00 UTC +00:00
[6] pry(main)> random_time_to_nearest_hour
=> Mon, 03 Jun 2013 08:00:00 UTC +00:00
[7] pry(main)>
Note that, this method will always floor down to the nearest hour, but since you are anyways generating a random time, it wont matter if this time is getting floor'ed down or getting round'ed. :)

active record query over datetime array

Given I have an array of datetimes:
array = [Sat, 30 Jul 2011 00:00:00 CEST +02:00, Sat, 30 Jul 2011 00:15:00 CEST +02:00, Sat, 30 Jul 2011 00:30:00 CEST +02:00, Sat, 30 Jul 2011 00:45:00 CEST +02:00
I want my model class method to return the datetimes that dont match (aren't scheduled)
Sat, 30 Jul 2011 00:00:00 CEST +02:00
#appointment.rb (with colum `date` as DateTime)
def self.booked(array)
where("date NOT IN (?)", array)
end
Thx for advise!
It's because your array is malformed:
array = [Sat, 30 Jul 2011 00:00:00 CEST +02:00, Sat, 30 Jul 2011 00:15:00 CEST +02:00, Sat, 30 Jul 2011 00:30:00 CEST +02:00, Sat, 30 Jul 2011 00:45:00 CEST +02:00
notice it's separating the days as individual elements. Or is this your doing? If not, you should probably convert them all to actual DateTime objects (using #parse probably) and then put them in the array.
Also, you might want to make that method into a scope:
scope :booked, lambda { |datetimes| where("date NOT IN (?)", datetimes) }
I'm guessing that date is actually a date in the database, not a datetime or timestamp. So, you need to convert your Ruby Datetimes to just Date instances:
def self.booked(array)
where("date NOT IN (?)", array.map(&:to_date))
end
If you don't convert them to Dates by hand, AR won't know that it is supposed to convert them to dates for the database; then, depending on the underlying database, you could get empty results or possibly errors.
Your code look fine to me, but you need to provide an array, like this:
where(['date NOT IN(?)', array])
Here is an example with a Webinar class with a date column
>> array = Webinar.all[0..2].map(&:date)
=> [Wed, 04 May 2011 02:16:00 PDT -07:00, Tue, 05 Apr 2011 06:00:00 PDT -07:00, Thu, 30 Jun 2011 07:30:00 PDT -07:00]
>> count_without_array = (Webinar.count - array.size)
>> Webinar.where(['date NOT IN(?)', array]).count == count_without_array
=> true
Keep in mind that date must be exact match, if there is 1 second difference its not going to work.

Resources