提交 a6e3cdae 编写于 作者: S Sean Griffin

Allow proc defaults with the Attributes API

This is a variant implementation of the changes proposed in #19914.
Unlike that PR, the change in behavior is isolated in its own class.
This is to prevent wonky behavior if a Proc is assigned outside of the
default, and it is a natural place to place the behavior required by #19921
as well.

Close #19914.

[Sean Griffin & Kir Shatrov]
上级 73aab036
require 'active_record/attribute'
module ActiveRecord
class Attribute # :nodoc:
class UserProvidedDefault < FromUser
def initialize(name, value, type)
super(name, value, type)
end
def type_cast(value)
if value.is_a?(Proc)
super(value.call)
else
super
end
end
end
end
end
require 'active_record/attribute/user_provided_default'
module ActiveRecord
# See ActiveRecord::Attributes::ClassMethods for documentation
module Attributes
......@@ -236,7 +238,11 @@ def define_default_attribute(name, value, type, from_user:)
if value == NO_DEFAULT_PROVIDED
default_attribute = _default_attributes[name].with_type(type)
elsif from_user
default_attribute = Attribute.from_user(name, value, type)
default_attribute = Attribute::UserProvidedDefault.new(
name,
value,
type,
)
else
default_attribute = Attribute.from_database(name, value, type)
end
......
......@@ -125,6 +125,16 @@ def deserialize(*)
assert_equal "from user", model.wibble
end
test "procs for default values" do
klass = Class.new(OverloadedType) do
@@counter = 0
attribute :counter, :integer, default: -> { @@counter += 1 }
end
assert_equal 1, klass.new.counter
assert_equal 2, klass.new.counter
end
if current_adapter?(:PostgreSQLAdapter)
test "arrays types can be specified" do
klass = Class.new(OverloadedType) do
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册