如何使用属性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,default: -> { starts_at.nil? ? Time.Now : starts_at + 1.hour }
end

解决方法

不,我认为这不可能。默认值是在类(而不是实例)的上下文中评估的。

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
  ends_at ||= starts_at.nil? ? Time.now : starts_at + 1.hour
end