Skip to content

Commit e7b050d

Browse files
authored
Merge pull request rails#43296 from the-spectator/filter_default_value
Fixes rails#43279 by filtering unchanged attributes when default function is available for insert
2 parents 0a751a0 + a630ed5 commit e7b050d

File tree

4 files changed

+43
-1
lines changed

4 files changed

+43
-1
lines changed

activerecord/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* Filter unchanged attributes with default function from insert query when `partial_inserts` is disabled.
2+
3+
*Akshay Birajdar*, *Jacopo Beschi*
4+
15
* Add support for FILTER clause (SQL:2003) to Arel.
26

37
Currently supported by PostgreSQL 9.4+ and SQLite 3.30+.

activerecord/lib/active_record/attribute_methods/dirty.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,13 @@ def attribute_names_for_partial_updates
229229
end
230230

231231
def attribute_names_for_partial_inserts
232-
partial_inserts? ? changed_attribute_names_to_save : attribute_names
232+
if partial_inserts?
233+
changed_attribute_names_to_save
234+
else
235+
attribute_names.reject do |attr_name|
236+
!attribute_changed?(attr_name) && column_for_attribute(attr_name).default_function
237+
end
238+
end
233239
end
234240
end
235241
end

activerecord/test/cases/dirty_test.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,37 @@ def check_around
941941
assert_not_predicate person, :changed?
942942
end
943943

944+
unless current_adapter?(:SQLite3Adapter)
945+
test "partial insert off with unchanged default function attribute" do
946+
with_partial_writes Aircraft, false do
947+
aircraft = Aircraft.new(name: "Boeing")
948+
assert_equal "Boeing", aircraft.name
949+
950+
aircraft.save!
951+
aircraft.reload
952+
953+
assert_equal "Boeing", aircraft.name
954+
assert_equal Time.now.utc.strftime("%Y-%m-%d %H:%M:%S"), aircraft.manufactured_at.strftime("%Y-%m-%d %H:%M:%S")
955+
end
956+
end
957+
958+
test "partial insert off with changed default function attribute" do
959+
with_partial_writes Aircraft, false do
960+
manufactured_at = 1.years.ago
961+
aircraft = Aircraft.new(name: "Boeing2", manufactured_at: manufactured_at)
962+
963+
assert_equal "Boeing2", aircraft.name
964+
assert_equal manufactured_at.to_i, aircraft.manufactured_at.to_i
965+
966+
aircraft.save!
967+
aircraft.reload
968+
969+
assert_equal "Boeing2", aircraft.name
970+
assert_equal manufactured_at.utc.strftime("%Y-%m-%d %H:%M:%S"), aircraft.manufactured_at.strftime("%Y-%m-%d %H:%M:%S")
971+
end
972+
end
973+
end
974+
944975
private
945976
def with_partial_writes(klass, on = true)
946977
old_inserts = klass.partial_inserts?

activerecord/test/schema/schema.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
t.string :name
3939
t.integer :wheels_count, default: 0, null: false
4040
t.datetime :wheels_owned_at
41+
t.timestamp :manufactured_at, default: -> { "CURRENT_TIMESTAMP" }
4142
end
4243

4344
create_table :articles, force: true do |t|

0 commit comments

Comments
 (0)