Enable mapping to nil in enums
Enum in Rails 5 does not map nil values - IOW nil value remains nil, even if there is a key with nil value in the enum definition. This commit overrides the underlying Enum methods so nil value is still mapped. This solution is far from being ideal: it uses dynamic definition of methods which introduces more magic/confusion into the codebase. It would be better to get rid of the nil value in enums.
This commit is contained in:
parent
41eab9a907
commit
0665a8f730
3 changed files with 38 additions and 21 deletions
|
@ -8,6 +8,7 @@ module Ci
|
|||
include Gitlab::OptimisticLocking
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
include AtomicInternalId
|
||||
include EnumWithNil
|
||||
|
||||
belongs_to :project, inverse_of: :pipelines
|
||||
belongs_to :user
|
||||
|
@ -54,7 +55,7 @@ module Ci
|
|||
|
||||
after_create :keep_around_commits, unless: :importing?
|
||||
|
||||
enum source: {
|
||||
enum_with_nil source: {
|
||||
unknown: nil,
|
||||
push: 1,
|
||||
web: 2,
|
||||
|
@ -64,7 +65,7 @@ module Ci
|
|||
external: 6
|
||||
}
|
||||
|
||||
enum config_source: {
|
||||
enum_with_nil config_source: {
|
||||
unknown_source: nil,
|
||||
repository_source: 1,
|
||||
auto_devops_source: 2
|
||||
|
@ -599,17 +600,6 @@ module Ci
|
|||
@latest_builds_with_artifacts ||= builds.latest.with_artifacts_archive.to_a
|
||||
end
|
||||
|
||||
# Rails 5.0 autogenerated question mark enum methods return wrong result if enum value is nil.
|
||||
# They always return `false`.
|
||||
# These methods overwrite autogenerated ones to return correct results.
|
||||
def unknown?
|
||||
Gitlab.rails5? ? source.nil? : super
|
||||
end
|
||||
|
||||
def unknown_source?
|
||||
Gitlab.rails5? ? config_source.nil? : super
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ci_yaml_from_repo
|
||||
|
|
|
@ -3,6 +3,7 @@ class CommitStatus < ActiveRecord::Base
|
|||
include Importable
|
||||
include AfterCommitQueue
|
||||
include Presentable
|
||||
include EnumWithNil
|
||||
|
||||
self.table_name = 'ci_builds'
|
||||
|
||||
|
@ -39,7 +40,7 @@ class CommitStatus < ActiveRecord::Base
|
|||
scope :retried_ordered, -> { retried.ordered.includes(project: :namespace) }
|
||||
scope :after_stage, -> (index) { where('stage_idx > ?', index) }
|
||||
|
||||
enum failure_reason: {
|
||||
enum_with_nil failure_reason: {
|
||||
unknown_failure: nil,
|
||||
script_failure: 1,
|
||||
api_failure: 2,
|
||||
|
@ -190,11 +191,4 @@ class CommitStatus < ActiveRecord::Base
|
|||
v =~ /\d+/ ? v.to_i : v
|
||||
end
|
||||
end
|
||||
|
||||
# Rails 5.0 autogenerated question mark enum methods return wrong result if enum value is nil.
|
||||
# They always return `false`.
|
||||
# This method overwrites the autogenerated one to return correct result.
|
||||
def unknown_failure?
|
||||
Gitlab.rails5? ? failure_reason.nil? : super
|
||||
end
|
||||
end
|
||||
|
|
33
app/models/concerns/enum_with_nil.rb
Normal file
33
app/models/concerns/enum_with_nil.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
module EnumWithNil
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
def self.enum_with_nil(definitions)
|
||||
# use original `enum` to auto-define all methods
|
||||
enum(definitions)
|
||||
|
||||
# override auto-defined methods only for the
|
||||
# key which uses nil value
|
||||
definitions.each do |name, values|
|
||||
next unless key_with_nil = values.key(nil)
|
||||
|
||||
# E.g. for enum_with_nil failure_reason: { unknown_failure: nil }
|
||||
# this overrides auto-generated method `unknown_failure?`
|
||||
define_method("#{key_with_nil}?") do
|
||||
Gitlab.rails5? ? self[name].nil? : super()
|
||||
end
|
||||
|
||||
# E.g. for enum_with_nil failure_reason: { unknown_failure: nil }
|
||||
# this overrides auto-generated method `failure_reason`
|
||||
define_method(name) do
|
||||
orig = super()
|
||||
|
||||
return orig unless Gitlab.rails5?
|
||||
return orig unless orig.nil?
|
||||
|
||||
self.class.public_send(name.to_s.pluralize).key(nil) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue