Skip to content

Commit

Permalink
Fix enum predicate methods on object enum keys
Browse files Browse the repository at this point in the history
Follow up #41278 to fix #41118.
  • Loading branch information
kamipo committed Feb 2, 2021
1 parent 56bcb83 commit 24416e5
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 10 deletions.
16 changes: 8 additions & 8 deletions activerecord/lib/active_record/enum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,14 @@ def enum(definitions)

value_method_name = "#{prefix}#{label}#{suffix}"
value_method_names << value_method_name
define_enum_methods(name, value_method_name, label, enum_scopes)
define_enum_methods(name, value_method_name, value, enum_scopes)

method_friendly_label = label.gsub(/[\W&&[:ascii:]]+/, "_")
value_method_alias = "#{prefix}#{method_friendly_label}#{suffix}"

if value_method_alias != value_method_name && !value_method_names.include?(value_method_alias)
value_method_names << value_method_alias
define_enum_methods(name, value_method_alias, label, enum_scopes)
define_enum_methods(name, value_method_alias, value, enum_scopes)
end
end
end
Expand All @@ -234,23 +234,23 @@ def initialize(klass)
private
attr_reader :klass

def define_enum_methods(name, value_method_name, label, enum_scopes)
# def active?() status == "active" end
def define_enum_methods(name, value_method_name, value, enum_scopes)
# def active?() status_for_database == 0 end
klass.send(:detect_enum_conflict!, name, "#{value_method_name}?")
define_method("#{value_method_name}?") { self[name] == label }
define_method("#{value_method_name}?") { public_send(:"#{name}_for_database") == value }

# def active!() update!(status: 0) end
klass.send(:detect_enum_conflict!, name, "#{value_method_name}!")
define_method("#{value_method_name}!") { update!(name => label) }
define_method("#{value_method_name}!") { update!(name => value) }

# scope :active, -> { where(status: 0) }
# scope :not_active, -> { where.not(status: 0) }
if enum_scopes != false
klass.send(:detect_enum_conflict!, name, value_method_name, true)
klass.scope value_method_name, -> { where(name => label) }
klass.scope value_method_name, -> { where(name => value) }

klass.send(:detect_enum_conflict!, name, "not_#{value_method_name}", true)
klass.scope "not_#{value_method_name}", -> { where.not(name => label) }
klass.scope "not_#{value_method_name}", -> { where.not(name => value) }
end
end
end
Expand Down
6 changes: 4 additions & 2 deletions activerecord/test/cases/enum_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -701,15 +701,17 @@ def self.name; "Book"; end
end

test "deserialize enum value to original hash key" do
proposed = Class.new
written = Class.new
proposed = Struct.new(:to_s).new("proposed")
written = Struct.new(:to_s).new("written")
klass = Class.new(ActiveRecord::Base) do
self.table_name = "books"
enum status: { proposed => 0, written => 1 }
end

book = klass.create!(status: 0)
assert_equal proposed, book.status
assert_predicate book, :proposed?
assert_not_predicate book, :written?
end

test "enum logs a warning if auto-generated negative scopes would clash with other enum names" do
Expand Down

0 comments on commit 24416e5

Please sign in to comment.