提交 8c793aa8 编写于 作者: R Ryuta Kamizono

Allow attribute's default to be configured but keeping its own type

```ruby
class Post < ActiveRecord::Base
  attribute :written_at, default: -> { Time.now.utc }
end

# Rails 6.0
Post.type_for_attribute(:written_at) # => #<Type::Value ... precision: nil, ...>

# Rails 6.1
Post.type_for_attribute(:written_at) # => #<Type::DateTime ... precision: 6, ...>
```

This is an alternative of #39797.

Context https://github.com/rails/rails/pull/39797#issuecomment-655191817.

If people intend to override the existing type on the attribute, usually
an overriding type is explicitly specified, so I agree that the current
behavior (drop existing type information if type is omitted) is
practically quite useless, and it is almost like a bug in that there is
no way to override just the default.

So I'd like to change the current behavior on existing attributes
without a deprecation as a fix.

Closes #39797.

See also https://github.com/kufu/activerecord-bitemporal/pull/57.
上级 04fe959b
* Allow attribute's default to be configured but keeping its own type.
```ruby
class Post < ActiveRecord::Base
attribute :written_at, default: -> { Time.now.utc }
end
# Rails 6.0
Post.type_for_attribute(:written_at) # => #<Type::Value ... precision: nil, ...>
# Rails 6.1
Post.type_for_attribute(:written_at) # => #<Type::DateTime ... precision: 6, ...>
```
*Ryuta Kamizono*
* Allow default to be configured for Enum.
```ruby
......
......@@ -253,7 +253,7 @@ def load_schema! # :nodoc:
when Proc
type = type[type_for_attribute(name)]
else
type ||= Type::Value.new
type ||= type_for_attribute(name)
end
define_attribute(name, type, **options.slice(:default))
......
......@@ -56,6 +56,18 @@ class CustomPropertiesTest < ActiveRecord::TestCase
assert_equal 255, UnoverloadedType.type_for_attribute("overloaded_string_with_limit").limit
end
test "overloaded default but keeping its own type" do
klass = Class.new(UnoverloadedType) do
attribute :overloaded_string_with_limit, default: "the overloaded default"
end
assert_equal 255, UnoverloadedType.type_for_attribute("overloaded_string_with_limit").limit
assert_equal 255, klass.type_for_attribute("overloaded_string_with_limit").limit
assert_nil UnoverloadedType.new.overloaded_string_with_limit
assert_equal "the overloaded default", klass.new.overloaded_string_with_limit
end
test "extra options are forwarded to the type caster constructor" do
klass = Class.new(OverloadedType) do
attribute :starts_at, :datetime, precision: 3, limit: 2, scale: 1
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册