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
Backport #25364 to 4-2-stable #25565
Backport #25364 to 4-2-stable #25565
Conversation
Tests are failing with sqlite3, but I don't think it is related to this. I'll investigate. |
Yes, seems it is related. |
Failing test was removed at 19537ec on master. |
Weird. But they are passing in 4-2-stable. Why they are broken in your branch? |
c7a15e7
to
8b49662
Compare
assert_equal '10.1', @conn.type_cast('10.1', c) | ||
|
||
c = Column.new(nil, 1, Type::Date.new) | ||
assert_equal '10.1', @conn.type_cast('10.1', c) |
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.
Actually this assert is unexpected behavior, I think.
Previously type casting against Type::Date
was not worked.
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.
Oh, now I understand it. So those tests still make sense because the column information is still being used differently from 5.0, but this assertion needs to be changed or removed
Currently `Type::Date#serialize` does not cast a value to a date object. It should be cast to a date object for finding by date column correctly working. Fixes rails#25354.
8b49662
to
226e1a3
Compare
@@ -71,7 +71,7 @@ def test_type_cast_string | |||
assert_equal '10.1', @conn.type_cast('10.1', c) | |||
|
|||
c = Column.new(nil, 1, Type::Date.new) | |||
assert_equal '10.1', @conn.type_cast('10.1', c) | |||
assert_equal '2016-05-11', @conn.type_cast('2016-05-11 19:00:00', c) |
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.
Changed this assertion to expected behavior!
@@ -9,6 +9,10 @@ def klass | |||
::Date | |||
end | |||
|
|||
def type_cast_for_database(value) |
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.
@kamipo I'm not sure this is sufficient to fix the underlying problem. I tried this same solution last night (as module included onto ActiveRecord::Type::Date
to monkey patch it), and I am seeing this method called in some cases, such as when persisting records; however, when calling where
on the model, it is still coercing to a UTC date time string. Here is an example (rspec) test:
describe 'querying dates with times works around day boundaries' do
let(:model_class) do
model_class = Class.new(ActiveRecord::Base)
model_class.table_name = 'date_serialization_test'
model_class
end
let!(:old_record) { model_class.create!(a_date_field: Date.new(2016, 6, 8)) }
let!(:boundary_record) { model_class.create!(a_date_field: Date.new(2016, 6, 9)) }
let!(:newer_record) { model_class.create!(a_date_field: Date.new(2016, 6, 10)) }
before(:context) do
ActiveRecord::Migration.new.create_table(:date_serialization_test) do |t|
t.date :a_date_field
end
end
after(:context) do
ActiveRecord::Migration.new.drop_table(:date_serialization_test)
end
it 'coerces TimeWithZone to Date in current locale' do
date = Time.new(2016, 6, 9, 23, 0, 0, '-05:00').in_time_zone
byebug
query = model_class.where('a_date_field >= ?', date)
expect(query).to include boundary_record, newer_record
expect(query).not_to include old_record
end
it 'coerces Time to Date in current locale' do
date = Time.new(2016, 6, 9, 23, 0, 0, '-05:00')
query = model_class.where('a_date_field >= ?', date)
expect(query).to include boundary_record, newer_record
expect(query).not_to include old_record
end
it 'coerces DateTime to Date in current locale' do
date = DateTime.new(2016, 6, 9, 23, 0, 0, '-5')
query = model_class.where('a_date_field >= ?', date)
binding.pry
expect(query).to include boundary_record, newer_record
expect(query).not_to include old_record
end
it 'queries still work correctly using a Date object' do
date = Date.new(2016, 6, 9)
query = model_class.where('a_date_field >= ?', date)
expect(query).to include boundary_record, newer_record
expect(query).not_to include old_record
end
end
I suspect that because the where
clause uses an SQL string, it may not be able to determine the column type? I am finding that my issue may not be quite the same as the case this and the relate rails 5 PR solves.
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 suspect that because the
where
clause uses an SQL string, it may not be able to determine the column type?
Right, AR cannot determine the column type if using where
with an SQL string for now.
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.
Yes, after further investigation I determined we need to just type cast the values ourselves. Thanks @kamipo
This PR is backport #25364 to 4-2-stable.
Currently
Type::Date#serialize
does not cast a value to a date object.It should be cast to a date object for finding by date column correctly
working.
Fixes #25354.
r? @rafaelfranca