Skip to content

Replace default_value_for with Rails attributes API

The current version of default_value_for does not support Rails 7 and it looks almost unmaintained: https://github.com/FooBarWidget/default_value_for/issues/92

In Rails 6 we can use the attributes API to set default values:

diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index 05a258e6e26..ae16cb1edf3 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -102,7 +102,7 @@ class CommitStatus < Ci::ApplicationRecord
   # extend this `Hash` with new values.
   enum_with_nil failure_reason: Enums::Ci::CommitStatus.failure_reasons
 
-  default_value_for :retried, false
+  attribute :retried, default: false
 
   ##
   # We still create some CommitStatuses outside of CreatePipelineService.
diff --git a/app/models/deploy_token.rb b/app/models/deploy_token.rb
index 20d19ec9541..39baf159c15 100644
--- a/app/models/deploy_token.rb
+++ b/app/models/deploy_token.rb
@@ -13,7 +13,7 @@ class DeployToken < ApplicationRecord
   GITLAB_DEPLOY_TOKEN_NAME = 'gitlab-deploy-token'
   REQUIRED_DEPENDENCY_PROXY_SCOPES = %i[read_registry write_registry].freeze
 
-  default_value_for(:expires_at) { Forever.date }
+  attribute :expires_at, default: -> { Forever.date }
 
   # Do NOT use this `user` for the authentication/authorization of the deploy tokens.
   # It's for the auditing purpose on Credential Inventory, only.

Previous discussion: &7875 (comment 1131452313)

Models that use this gem:

  • AlertManagement::HttpIntegration
  • Appearance
  • ApplicationSetting
  • ApprovalProjectRule
  • BroadcastMessage
  • Ci::Build
  • Ci::BuildTraceChunk
  • Ci::SecureFile
  • Clusters::Applications::CertManager
  • Clusters::Applications::Crossplane
  • Clusters::Applications::Helm
  • Clusters::Applications::Ingress
  • Clusters::Applications::Jupyter
  • Clusters::Applications::Knative
  • Clusters::Applications::Prometheus
  • Clusters::Applications::Runner
  • Clusters::Cluster
  • Clusters::Integrations::Prometheus
  • Clusters::Platforms::Kubernetes
  • Clusters::Providers::Aws
  • Clusters::Providers::Gcp
  • CommitStatus
  • DependencyProxy::Blob
  • DependencyProxy::GroupSetting
  • DependencyProxy::Manifest
  • DeployToken
  • Epic
  • GitlabSubscription
  • Groups::FeatureSetting
  • Groups::RepositoryStorageMove
  • Integration
  • Issue
  • Label
  • Member
  • MergeRequest
  • Ml::Candidate
  • Note
  • NotificationSetting
  • Operations::FeatureFlag
  • PagesDomain
  • Project
  • ProjectCiCdSetting
  • ProjectFeature
  • ProjectSetting
  • ProjectStatistics
  • Projects::RepositoryStorageMove
  • Serverless::DomainCluster
  • Snippets::RepositoryStorageMove
  • Terraform::State
  • Terraform::StateVersion
  • TimeTracking::TimelogCategory
  • User
  • UserPreference

You can use _default: :mystring for enum and after_initialize if: :new_record? for attr_encrypted attribute.

ApplicationRecord.descendants.reject(&:abstract_class?).select {|klass| klass.try(:_default_attribute_values?) && !(!klass.superclass.abstract_class? && klass._default_attributes.keys == klass.superclass._default_attributes.keys)}.map(&:name).sort.map { |model| " - [ ] `#{model}`" }.join("\n")
Edited by Igor Drozdov