I have an two-element array of ActiveRecord objects, slots_to_import
. These objects have begin_at
columns, and thus attributes. I was trying to get objects that have unique begin_at
values. Alas, slots_to_import.uniq_by(&:begin_at)
did not work. But the begin_at
values are equal for the two objects:
(rdb:1) p slots_to_import.first.begin_at == slots_to_import.last.begin_at
true
(rdb:1) p slots_to_import.uniq_by(&:begin_at).map(&:begin_at)
[Mon, 26 Nov 2012 19:00:00 UTC +00:00, Mon, 26 Nov 2012 19:00:00 UTC +00:00]
(rdb:1) p [slots_to_import.first.begin_at, slots_to_import.last.begin_at].uniq
[Mon, 26 Nov 2012 19:00:00 UTC +00:00, Mon, 26 Nov 2012 19:00:00 UTC +00:00]
Some more checking around:
(rdb:1) p [slots_to_import.first.begin_at.to_datetime, slots_to_import.last.begin_at.to_datetime].uniq
[Mon, 26 Nov 2012 19:00:00 +0000]
(rdb:1) p [slots_to_import.first.begin_at.usec, slots_to_import.last.begin_at.usec].uniq
[0]
(rdb:1) p [slots_to_import.first.begin_at.to_f, slots_to_import.last.begin_at.to_f].uniq
[1353956400.0]
(rdb:1) p [slots_to_import.first.begin_at.utc, slots_to_import.last.begin_at.utc].uniq
[Mon, 26 Nov 2012 19:00:00 +0000]
(rdb:1) p [slots_to_import.first.begin_at, slots_to_import.last.begin_at].uniq
[Mon, 26 Nov 2012 19:00:00 UTC +00:00, Mon, 26 Nov 2012 19:00:00 UTC +00:00]
I thought perhaps that uniq was checking whether they were the same object (since they were not). But no, some noodling in my rails console showed me that it does not use an object id check:
1.8.7 :111 > x = Time.zone.parse("Mon, 29 Oct 2012 19:29:17 UTC +00:00")
=> Mon, 29 Oct 2012 19:29:17 UTC +00:00
1.8.7 :112 > y = Time.zone.parse("Mon, 29 Oct 2012 19:29:17 UTC +00:00")
=> Mon, 29 Oct 2012 19:29:17 UTC +00:00
1.8.7 :113 > x == y
=> true
1.8.7 :114 > [x, y].uniq
=> [Mon, 29 Oct 2012 19:29:17 UTC +00:00]
I'm using Ruby 1.8.7p358 and ActiveSupport 3.2.0. BTW, I can solve my own issue by simply adding a to_datetime
, but I'm really curious why this isn't working without a conversion.
I thought you were working with plain Time
objects, so I started by looking at time.c
from the Ruby platform source (1.9.3). If they were Ruby 1.9.3 Time
objects, you could try:
[x.to_r, y.to_r]
Now I know you're working with ActiveSupport::TimeWithZone
objects. (As a suggestion, it would be good to mention key information like this next time you post a question.) Here is the body of ActiveSupport::TimeWithZone#eql?
:
def eql?(other)
utc == other
end
And here is the hash function:
alias :hash, :to_i
So the next step is for you to show what you get from [x.utc, y.utc, x.to_i, y.to_i, x.utc.class, y.utc.class]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With