aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/lib/active_record/persistence.rb15
-rw-r--r--activerecord/test/cases/adapter_test.rb14
-rw-r--r--activesupport/CHANGELOG.md5
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/calculations.rb2
-rw-r--r--activesupport/test/core_ext/date_time_ext_test.rb3
-rw-r--r--guides/source/4_0_release_notes.md2
6 files changed, 37 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 3f98d8f217..347f023793 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -429,13 +429,22 @@ module ActiveRecord
# Returns the number of affected rows.
def update_record(attribute_names = @attributes.keys)
attributes_with_values = arel_attributes_with_values_for_update(attribute_names)
-
if attributes_with_values.empty?
0
else
klass = self.class
- stmt = klass.unscoped.where(klass.arel_table[klass.primary_key].eq(id)).arel.compile_update(attributes_with_values)
- klass.connection.update stmt
+ column_hash = klass.connection.schema_cache.columns_hash klass.table_name
+ db_columns_with_values = attributes_with_values.map { |attr,value|
+ real_column = column_hash[attr.name]
+ [real_column, value]
+ }
+ bind_attrs = attributes_with_values.dup
+ bind_attrs.keys.each_with_index do |column, i|
+ real_column = db_columns_with_values[i].first
+ bind_attrs[column] = klass.connection.substitute_at(real_column, i)
+ end
+ stmt = klass.unscoped.where(klass.arel_table[klass.primary_key].eq(id)).arel.compile_update(bind_attrs)
+ klass.connection.update stmt, 'SQL', db_columns_with_values
end
end
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index f9149c1819..0af7cbf74f 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -1,4 +1,5 @@
require "cases/helper"
+require "models/book"
module ActiveRecord
class AdapterTest < ActiveRecord::TestCase
@@ -6,6 +7,19 @@ module ActiveRecord
@connection = ActiveRecord::Base.connection
end
+ ##
+ # PostgreSQL does not support null bytes in strings
+ unless current_adapter?(:PostgreSQLAdapter)
+ def test_update_prepared_statement
+ b = Book.create(name: "my \x00 book")
+ b.reload
+ assert_equal "my \x00 book", b.name
+ b.update_attributes(name: "my other \x00 book")
+ b.reload
+ assert_equal "my other \x00 book", b.name
+ end
+ end
+
def test_tables
tables = @connection.tables
assert tables.include?("accounts")
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 2515d378fd..b07ab749a3 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,5 +1,10 @@
## Rails 4.0.0 (unreleased) ##
+* Prevent `DateTime#change` from truncating the second fraction, when seconds
+ do not need to be changed.
+
+ *Chris Baynes*
+
* Added `ActiveSupport::TimeWithZone#to_r` for `Time#at` compatibility.
Before this change:
diff --git a/activesupport/lib/active_support/core_ext/date_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_time/calculations.rb
index 97aad008f5..9f0864d9bb 100644
--- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb
@@ -59,7 +59,7 @@ class DateTime
options.fetch(:day, day),
options.fetch(:hour, hour),
options.fetch(:min, options[:hour] ? 0 : min),
- options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec),
+ options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec + sec_fraction),
options.fetch(:offset, offset),
options.fetch(:start, start)
)
diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb
index 59ca2a4059..7be578599b 100644
--- a/activesupport/test/core_ext/date_time_ext_test.rb
+++ b/activesupport/test/core_ext/date_time_ext_test.rb
@@ -129,6 +129,9 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase
assert_equal DateTime.civil(2005,2,22,16), DateTime.civil(2005,2,22,15,15,10).change(:hour => 16)
assert_equal DateTime.civil(2005,2,22,16,45), DateTime.civil(2005,2,22,15,15,10).change(:hour => 16, :min => 45)
assert_equal DateTime.civil(2005,2,22,15,45), DateTime.civil(2005,2,22,15,15,10).change(:min => 45)
+
+ # datetime with fractions of a second
+ assert_equal DateTime.civil(2005,2,1,15,15,10.7), DateTime.civil(2005,2,22,15,15,10.7).change(:day => 1)
end
def test_advance
diff --git a/guides/source/4_0_release_notes.md b/guides/source/4_0_release_notes.md
index 9c157ec0b3..463da488f2 100644
--- a/guides/source/4_0_release_notes.md
+++ b/guides/source/4_0_release_notes.md
@@ -200,6 +200,8 @@ Please refer to the [Changelog](https://github.com/rails/rails/blob/master/activ
* Remove IdentityMap.
+* Remove automatic execution of EXPLAIN queries. The option `active_record.auto_explain_threshold_in_seconds` is no longer used and should be removed.
+
* Adds `ActiveRecord::NullRelation` and `ActiveRecord::Relation#none` implementing the null object pattern for the Relation class.
* Added `create_join_table` migration helper to create HABTM join tables.