Skip to content

Commit b63701e

Browse files
committed
update_columns raises if the column is unknown
Previosly, `update_columns` would just take whatever keys you gave it and tried to run the update query. Most likely this would result in an error from the database. However, if the column actually did exist, but was in `ignored_columns`, this would result in the method returning successfully when it should have raised, and an attribute that should not exist written to `@attributes`.
1 parent 9a18a10 commit b63701e

File tree

4 files changed

+16
-4
lines changed

4 files changed

+16
-4
lines changed

activemodel/lib/active_model/attribute.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ def with_value_from_database(value)
206206
raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{name}`"
207207
end
208208
alias_method :with_value_from_user, :with_value_from_database
209+
alias_method :with_cast_value, :with_value_from_database
209210
end
210211

211212
class Uninitialized < Attribute # :nodoc:

activerecord/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
* `update_columns` now correctly raises `ActiveModel::MissingAttributeError`
2+
if the attribute does not exist.
3+
4+
*Sean Griffin*
5+
16
* Add support for hash and url configs in database hash of `ActiveRecord::Base.connected_to`.
27

38
````

activerecord/lib/active_record/persistence.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,15 +479,15 @@ def update_columns(attributes)
479479
verify_readonly_attribute(key.to_s)
480480
end
481481

482+
attributes.each do |k, v|
483+
write_attribute_without_type_cast(k, v)
484+
end
485+
482486
affected_rows = self.class._update_record(
483487
attributes,
484488
self.class.primary_key => id_in_database
485489
)
486490

487-
attributes.each do |k, v|
488-
write_attribute_without_type_cast(k, v)
489-
end
490-
491491
affected_rows == 1
492492
end
493493

activerecord/test/cases/attribute_methods_test.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,12 @@ def setup
310310
assert_equal "New topic", topic.title
311311
end
312312

313+
test "write_attribute raises ActiveModel::MissingAttributeError when the attribute does not exist" do
314+
topic = Topic.first
315+
assert_raises(ActiveModel::MissingAttributeError) { topic.update_columns(no_column_exists: "Hello!") }
316+
assert_raises(ActiveModel::UnknownAttributeError) { topic.update(no_column_exists: "Hello!") }
317+
end
318+
313319
test "read_attribute" do
314320
topic = Topic.new
315321
topic.title = "Don't change the topic"

0 commit comments

Comments
 (0)