如何使用属性 API 设置虚拟属性的默认值
How to to set the default value of a virtual attribute using the attribute API
属性 API 让我可以像这样设置默认值
class Enrollment < ActiveRecord::Base
attribute :end_time, :datetime, default: -> { Time.now }
end
是否可以根据模型中的列设置默认值?以下无效
class CreateEnrollments < ActiveRecord::Migration[6.0]
def change
create_table :enrollments do |t|
t.datetime :starts_at
end
end
end
class Enrollment < ActiveRecord::Base
attribute :end_time, :datetime, default: -> { starts_at.nil? ? Time.now : starts_at + 1.hour }
end
不,我认为这不可能。默认值是在 class 的上下文中计算的 - 而不是实例。
class Foo
include ActiveModel::Model
include ActiveModel::Attributes
attribute :bar, default: ->{ self.name }
end
irb(main):051:0> Foo.new.bar
=> "Foo"
您可以做的是覆盖 initialize
方法:
def initialize(**attributes)
super
self.ends_at ||= starts_at.nil? ? Time.now : starts_at + 1.hour
end
属性 API 让我可以像这样设置默认值
class Enrollment < ActiveRecord::Base
attribute :end_time, :datetime, default: -> { Time.now }
end
是否可以根据模型中的列设置默认值?以下无效
class CreateEnrollments < ActiveRecord::Migration[6.0]
def change
create_table :enrollments do |t|
t.datetime :starts_at
end
end
end
class Enrollment < ActiveRecord::Base
attribute :end_time, :datetime, default: -> { starts_at.nil? ? Time.now : starts_at + 1.hour }
end
不,我认为这不可能。默认值是在 class 的上下文中计算的 - 而不是实例。
class Foo
include ActiveModel::Model
include ActiveModel::Attributes
attribute :bar, default: ->{ self.name }
end
irb(main):051:0> Foo.new.bar
=> "Foo"
您可以做的是覆盖 initialize
方法:
def initialize(**attributes)
super
self.ends_at ||= starts_at.nil? ? Time.now : starts_at + 1.hour
end