Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to to set the default value of a virtual attribute using the attribute API

The attribute API lets me set default values like this

class Enrollment < ActiveRecord::Base
  attribute :end_time, :datetime, default: -> { Time.now }
end

Is it possible to set the default value based on a column in the model? The following does not work

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
like image 256
vince Avatar asked Oct 17 '25 15:10

vince


1 Answers

No I don't think its possible. The default is evaluated in the context of the class - not the instance.

class Foo
  include ActiveModel::Model
  include ActiveModel::Attributes
  attribute :bar, default: ->{ self.name }
end 
irb(main):051:0> Foo.new.bar
=> "Foo"

What you can do is override the initialize method:

def initialize(**attributes)
  super
  self.ends_at ||= starts_at.nil? ? Time.now : starts_at + 1.hour
end
like image 50
max Avatar answered Oct 19 '25 13:10

max