-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use UTC when encoding datetime values into cursor. #92
Conversation
Hello @xijo and thanks for opening a PR. I did a bit of research and it looks like only attributes of type Other types such as It looks like this can be customized according to the docs I linked above, possibly making the conversion to UTC problematic. I guess this is what you mean when you say it would be a "breaking change" for some users. What about skipping the conversion to UTC if we detect that the application is set to |
Hi @aaronsama, according to the docs that you've linked:
Going with the principle of least surprise, having the gem work out of the box for the current rails default seems like the right thing to do, right? As for respecting the configuration, that is a solid plan, I'll add that to the PR. 👍 Just to clarify my current use case a bit. We're storing a field |
336a1e8
to
6229fd1
Compare
@aaronsama PR is updated accordingly, added a couple more test cases as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks again for your PR. I added some comments to improve the tests a bit. In general I would try to avoid having the timezone related configuration modified for the whole suite and move it to the tests where it's needed. Please have a look if it makes sense to you.
@@ -35,6 +39,7 @@ class Post < ActiveRecord::Base; end | |||
ActiveRecord::Migration.create_table :posts do |t| | |||
t.string :author | |||
t.string :content | |||
t.datetime :created_at |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about adding two test cases, one for timestamps and one for a datetime attribute? They are slightly different and would better reflect a real world scenario
t.datetime :created_at | |
t.timestamps | |
t.datetime :some_other_datetime_field |
# Configure time_zone like it would be in rails applications | ||
ActiveRecord::Base.time_zone_aware_attributes = true | ||
Time.zone = 'Berlin' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather mock the response values or change the setup only in the tests where we need it rather than changing the configuration for the whole test suite. Something like the code below would be enough probably.
# This can be different for different contexts
before do
ActiveRecord::Base.time_zone_aware_attributes = true
Time.zone = 'Berlin'
end
after do
# what you did in the file above
end
It looks like stubbing Time.zone
can be problematic but I found this: https://stackoverflow.com/a/26741932
it 'respects the time_zone_aware_attributes setting' do | ||
ActiveRecord::Base.time_zone_aware_attributes = false | ||
|
||
expect(decoded_time).to eq record.created_at | ||
expect(decoded_time).not_to be_utc | ||
end | ||
|
||
it 'respects the default_timezone setting' do | ||
ActiveRecord::Base.default_timezone = :local | ||
|
||
expect(decoded_time).to eq record.created_at | ||
expect(decoded_time).not_to be_utc | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you are altering the context in which these examples are run I propose moving them to their own context. See the comment below.
Something like
context 'when timezone aware attributes are disabled' do
before do
ActiveRecord::Base.time_zone_aware_attributes = false
end
# your examples here
end
context 'when using :local as default timezone' do
before do
ActiveRecord::Base.default_timezone = :local
end
# your examples here
end
@@ -51,6 +51,45 @@ | |||
expect(decoded.order_field_value).to eq record.author | |||
end | |||
end | |||
|
|||
context 'when ordering by created_at' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would try to make this more generig
context 'when ordering by created_at' do | |
context 'when ordering by a timestamp attribute' do |
This is addressed in #142 now. Closing this PR. |
Hello,
Rails stores datetime values in the DB as UTC as a default. When using a custom
order_by
on a datetime field, e.g.updated_at
however, theorder_field_value
is encoded in the local time zone, which leads to faulty pagination.This PR fixes this issue by always treating the value as UTC if it responds to
utc
. To provide a meaningful test case I've change the spec setup slightly, so that it operates in a different time zone, but still treats datetimes correctly.To some users, if they were deviating from rails defaults and stored datetimes in local time, this might be a breaking change. However, I'd assume that majority of rails applications adheres to the default.