Skip to content

Commit 435fdfb

Browse files
authored
Merge pull request rails#49982 from jean-francois-labbe/better-support-for-enum-with-symbol-values
[Fix rails#49981] Support enum definition with symbol values
2 parents a807d58 + 2dc080f commit 435fdfb

File tree

5 files changed

+35
-2
lines changed

5 files changed

+35
-2
lines changed

activerecord/lib/active_record/enum.rb

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ def enum(name, values = nil, **options)
220220

221221
private
222222
def _enum(name, values, prefix: nil, suffix: nil, scopes: true, instance_methods: true, validate: false, **options)
223-
assert_valid_enum_definition_values(values)
223+
values = assert_valid_enum_definition_values(values)
224224
assert_valid_enum_options(options)
225225

226226
# statuses = { }
@@ -341,6 +341,20 @@ def assert_valid_enum_definition_values(values)
341341
if values.keys.any?(&:blank?)
342342
raise ArgumentError, "Enum values #{values} must not contain a blank name."
343343
end
344+
345+
values = values.transform_values do |value|
346+
value.is_a?(Symbol) ? value.name : value
347+
end
348+
349+
values.each_value do |value|
350+
case value
351+
when String, Integer, true, false, nil
352+
# noop
353+
else
354+
raise ArgumentError, "Enum values #{values} must be only booleans, integers, symbols or strings, got: #{value.class}"
355+
end
356+
end
357+
344358
when Array
345359
if values.empty?
346360
raise ArgumentError, "Enum values #{values} must not be empty."
@@ -356,6 +370,8 @@ def assert_valid_enum_definition_values(values)
356370
else
357371
raise ArgumentError, "Enum values #{values} must be either a non-empty hash or an array."
358372
end
373+
374+
values
359375
end
360376

361377
def assert_valid_enum_options(options)

activerecord/test/cases/enum_test.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,15 @@ def self.name; "Book"; end
493493

494494
assert_match(/must not contain a blank name\.$/, e.message)
495495

496+
e = assert_raises(ArgumentError) do
497+
Class.new(ActiveRecord::Base) do
498+
self.table_name = "books"
499+
enum :status, { proposed: Object.new, active: :active }
500+
end
501+
end
502+
503+
assert_match(/must be only booleans, integers, symbols or strings/, e.message)
504+
496505
e = assert_raises(ArgumentError) do
497506
Class.new(ActiveRecord::Base) do
498507
self.table_name = "books"
@@ -715,6 +724,12 @@ def self.name; "Book"; end
715724
assert_equal "proposed", book.aliased_status
716725
end
717726

727+
test "enum with a hash with symbol values" do
728+
book = Book.create!(symbol_status: :proposed)
729+
assert_equal "proposed", book.symbol_status
730+
assert_predicate book, :symbol_status_proposed?
731+
end
732+
718733
test "query state by predicate with prefix" do
719734
assert_predicate @book, :author_visibility_visible?
720735
assert_not_predicate @book, :author_visibility_invisible?

activerecord/test/models/book.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class Book < ActiveRecord::Base
2424
enum :difficulty, [:easy, :medium, :hard], suffix: :to_read
2525
enum :cover, { hard: "hard", soft: "soft" }
2626
enum :boolean_status, { enabled: true, disabled: false }
27+
enum :symbol_status, { proposed: :proposed, published: :published }, prefix: true
2728

2829
def published!
2930
super

activerecord/test/schema/schema.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
t.column :font_size, :integer, **default_zero
139139
t.column :difficulty, :integer, **default_zero
140140
t.column :cover, :string, default: "hard"
141+
t.column :symbol_status, :string, default: "proposed"
141142
t.string :isbn
142143
t.string :external_id
143144
t.column :original_name, :string

guides/source/active_record_validations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,7 @@ A `:conditions` option can be used to specify additional conditions as a `WHERE`
917917
SQL fragment to limit the uniqueness constraint lookup:
918918

919919
```ruby
920-
validates :name, uniqueness: { conditions: -> { where(status: 'active') } }
920+
validates :name, uniqueness: { conditions: -> { where(status: "active") } }
921921
```
922922

923923
The default error message is _"has already been taken"_.

0 commit comments

Comments
 (0)