aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/attributes_test.rb
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2015-01-30 14:03:36 -0700
committerSean Griffin <sean@thoughtbot.com>2015-01-31 19:42:38 -0700
commit70ac072976c8cc6f013f0df3777e54ccae3f4f8c (patch)
tree7a9d376fa4b2694c9b214da3cb8205ca1bcb3406 /activerecord/test/cases/attributes_test.rb
parente2ccfebab4fd37603546998df2ee57b8bb07c168 (diff)
downloadrails-70ac072976c8cc6f013f0df3777e54ccae3f4f8c.tar.gz
rails-70ac072976c8cc6f013f0df3777e54ccae3f4f8c.tar.bz2
rails-70ac072976c8cc6f013f0df3777e54ccae3f4f8c.zip
Attribute assignment and type casting has nothing to do with columns
It's finally finished!!!!!!! The reason the Attributes API was kept private in 4.2 was due to some publicly visible implementation details. It was previously implemented by overloading `columns` and `columns_hash`, to make them return column objects which were modified with the attribute information. This meant that those methods LIED! We didn't change the database schema. We changed the attribute information on the class. That is wrong! It should be the other way around, where schema loading just calls the attributes API for you. And now it does! Yes, this means that there is nothing that happens in automatic schema loading that you couldn't manually do yourself. (There's still some funky cases where we hit the connection adapter that I need to handle, before we can turn off automatic schema detection entirely.) There were a few weird test failures caused by this that had to be fixed. The main source came from the fact that the attribute methods are now defined in terms of `attribute_names`, which has a clause like `return [] unless table_exists?`. I don't *think* this is an issue, since the only place this caused failures were in a fake adapter which didn't override `table_exists?`. Additionally, there were a few cases where tests were failing because a migration was run, but the model was not reloaded. I'm not sure why these started failing from this change, I might need to clear an additional cache in `reload_schema_from_cache`. Again, since this is not normal usage, and it's expected that `reset_column_information` will be called after the table is modified, I don't think it's a problem. Still, test failures that were unrelated to the change are worrying, and I need to dig into them further. Finally, I spent a lot of time debugging issues with the mutex used in `define_attribute_methods`. I think we can just remove that method entirely, and define the attribute methods *manually* in the call to `define_attribute`, which would simplify the code *tremendously*. Ok. now to make this damn thing public, and work on moving it up to Active Model.
Diffstat (limited to 'activerecord/test/cases/attributes_test.rb')
-rw-r--r--activerecord/test/cases/attributes_test.rb43
1 files changed, 28 insertions, 15 deletions
diff --git a/activerecord/test/cases/attributes_test.rb b/activerecord/test/cases/attributes_test.rb
index 4ddf6e7ba0..6f331c5985 100644
--- a/activerecord/test/cases/attributes_test.rb
+++ b/activerecord/test/cases/attributes_test.rb
@@ -50,8 +50,8 @@ module ActiveRecord
end
test "overloaded properties with limit" do
- assert_equal 50, OverloadedType.columns_hash['overloaded_string_with_limit'].limit
- assert_equal 255, UnoverloadedType.columns_hash['overloaded_string_with_limit'].limit
+ assert_equal 50, OverloadedType.type_for_attribute('overloaded_string_with_limit').limit
+ assert_equal 255, UnoverloadedType.type_for_attribute('overloaded_string_with_limit').limit
end
test "nonexistent attribute" do
@@ -87,29 +87,42 @@ module ActiveRecord
assert_equal 4.4, data.overloaded_float
end
- test "overloading properties does not change column order" do
- column_names = OverloadedType.column_names
- assert_equal %w(id overloaded_float unoverloaded_float overloaded_string_with_limit string_with_default non_existent_decimal), column_names
+ test "overloading properties does not attribute method order" do
+ attribute_names = OverloadedType.attribute_names
+ assert_equal %w(id overloaded_float unoverloaded_float overloaded_string_with_limit string_with_default non_existent_decimal), attribute_names
end
test "caches are cleared" do
klass = Class.new(OverloadedType)
- assert_equal 6, klass.columns.length
- assert_not klass.columns_hash.key?('wibble')
- assert_equal 6, klass.column_types.length
+ assert_equal 6, klass.attribute_types.length
assert_equal 6, klass.column_defaults.length
- assert_not klass.column_names.include?('wibble')
- assert_equal 5, klass.content_columns.length
+ assert_not klass.attribute_types.include?('wibble')
klass.attribute :wibble, Type::Value.new
- assert_equal 7, klass.columns.length
- assert klass.columns_hash.key?('wibble')
- assert_equal 7, klass.column_types.length
+ assert_equal 7, klass.attribute_types.length
assert_equal 7, klass.column_defaults.length
- assert klass.column_names.include?('wibble')
- assert_equal 6, klass.content_columns.length
+ assert klass.attribute_types.include?('wibble')
+ end
+
+ test "the given default value is cast from user" do
+ custom_type = Class.new(Type::Value) do
+ def type_cast_from_user(*)
+ "from user"
+ end
+
+ def type_cast_from_database(*)
+ "from database"
+ end
+ end
+
+ klass = Class.new(OverloadedType) do
+ attribute :wibble, custom_type.new, default: "default"
+ end
+ model = klass.new
+
+ assert_equal "from user", model.wibble
end
end
end