diff options
author | Sean Griffin <sean@seantheprogrammer.com> | 2016-07-25 11:06:04 -0400 |
---|---|---|
committer | Sean Griffin <sean@seantheprogrammer.com> | 2016-07-25 11:12:06 -0400 |
commit | f0ddf87e4bfcfcb861b0a9dca32edb733668bd30 (patch) | |
tree | 37e30078178423e3b7f8850ab7b667f70db9abfc /activerecord/test/cases | |
parent | 7ebef567ce30d848dd8f9374fd70699fd91acb29 (diff) | |
download | rails-f0ddf87e4bfcfcb861b0a9dca32edb733668bd30.tar.gz rails-f0ddf87e4bfcfcb861b0a9dca32edb733668bd30.tar.bz2 rails-f0ddf87e4bfcfcb861b0a9dca32edb733668bd30.zip |
Correct the behavior of virtual attributes on models loaded from the db
Previously we had primarily tested the behavior of these attributes by
calling `.new`, allowing this to slip through the cracks. There were a
few ways in which they were behaving incorrectly.
The biggest issue was that attempting to read the attribute would
through a `MissingAttribute` error. We've corrected this by returning
the default value when the attribute isn't backed by a database column.
This is super special cased, but I don't see a way to avoid this
conditional. I had considered handling this higher up in
`define_default_attribute`, but we don't have the relevant information
there as users can provide new defaults for database columns as well.
Once I corrected this, I had noticed that the attributes were always
being marked as changed. This is because the behavior of
`define_default_attribute` was treating them as assigned from
`Attribute::Null`.
Finally, with our new implementation, `LazyAttributeHash` could no
longer be marshalled, as it holds onto a proc. This has been corrected
as well. I've not handled YAML in that class, as we do additional work
higher up to avoid YAML dumping it at all.
Fixes #25787
Close #25841
Diffstat (limited to 'activerecord/test/cases')
-rw-r--r-- | activerecord/test/cases/attributes_test.rb | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/activerecord/test/cases/attributes_test.rb b/activerecord/test/cases/attributes_test.rb index 7bcaa53aa2..604411da97 100644 --- a/activerecord/test/cases/attributes_test.rb +++ b/activerecord/test/cases/attributes_test.rb @@ -205,5 +205,49 @@ module ActiveRecord assert_equal(:bar, child.new(foo: :bar).foo) end + + test "attributes not backed by database columns are not dirty when unchanged" do + refute OverloadedType.new.non_existent_decimal_changed? + end + + test "attributes not backed by database columns are always initialized" do + OverloadedType.create! + model = OverloadedType.first + + assert_nil model.non_existent_decimal + model.non_existent_decimal = "123" + assert_equal 123, model.non_existent_decimal + end + + test "attributes not backed by database columns return the default on models loaded from database" do + child = Class.new(OverloadedType) do + attribute :non_existent_decimal, :decimal, default: 123 + end + child.create! + model = child.first + + assert_equal 123, model.non_existent_decimal + end + + test "attributes not backed by database columns properly interact with mutation and dirty" do + child = Class.new(ActiveRecord::Base) do + self.table_name = "topics" + attribute :foo, :string, default: "lol" + end + child.create! + model = child.first + + assert_equal "lol", model.foo + + model.foo << "asdf" + assert_equal "lolasdf", model.foo + assert model.foo_changed? + + model.reload + assert_equal "lol", model.foo + + model.foo = "lol" + refute model.changed? + end end end |