Skip to content

Commit 8c54251

Browse files
skipkayhilrafaelfranca
authored andcommitted
Deprecate defining enums with keywords args
Enums have historically been defined using keyword arguments: ```ruby class Function > ApplicationRecord enum color: [:red, :blue], type: [:instance, :class], _scopes: false ``` This has the advantage of being able to define multiple enums at once with the same options. However, it also has a downside that enum options must be prefixed with an underscore to separate them from the enum definitions (to enable models to have enums with the same name as an option). In Rails 7, a new syntax was [introduced][1] to instead define enums with positional arguments: ```ruby class Function > ApplicationRecord enum :color, [:red, :blue], scopes: false enum :type, [:instance, :class], scopes: false ``` This new syntax eliminates the need to prefix options with an underscore, and the docs were updated to recommend this new syntax. However, both versions of the API have been supported since, and it has started to cause some problems: The first issue is that the available options have drifted. In Rails 7.1, an option was added to make assigning an invalid enum value use validation errors instead of runtime errors. However, the equivalent underscored prefix option was not added for the original enum syntax Articles have been created that describe the new option in Rails 7.1, but the examples in the articles use un-prefixed options with the old syntax. This confusion has also lead to issues opened asking why that incorrect syntax is not working. Additionally, the presence of underscored options is just generally confusing because it tends to imply an option is for internal use. This commit aims to fix all of these issues by deprecating the old enum syntax. With only one way to define enums, options cannot drift and there will be less confusion around how enums should be defined. [1]: 0618d2d
1 parent f0adde9 commit 8c54251

File tree

12 files changed

+198
-122
lines changed

12 files changed

+198
-122
lines changed

activerecord/CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
* Deprecate defining an `enum` with keyword arguments.
2+
3+
```ruby
4+
class Function > ApplicationRecord
5+
# BAD
6+
enum color: [:red, :blue],
7+
type: [:instance, :class]
8+
9+
# GOOD
10+
enum :color, [:red, :blue]
11+
enum :type, [:instance, :class]
12+
end
13+
```
14+
15+
*Hartley McGuire*
16+
117
* Add `active_record.config.validate_migration_timestamps` option for validating migration timestamps.
218

319
When set, validates that the timestamp prefix for a migration is no more than a day ahead of

activerecord/lib/active_record/enum.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,13 @@ def enum(name = nil, values = nil, **options)
223223
options.transform_keys! { |key| :"#{key[1..-1]}" }
224224

225225
definitions.each { |name, values| _enum(name, values, **options) }
226+
227+
ActiveRecord.deprecator.warn(<<~MSG)
228+
Defining enums with keyword arguments is deprecated and will be removed
229+
in Rails 7.3. Positional arguments should be used instead:
230+
231+
#{definitions.map { |name, values| "enum :#{name}, #{values}" }.join("\n")}
232+
MSG
226233
end
227234

228235
private

activerecord/test/cases/associations/has_many_associations_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ class SpecialBook < ActiveRecord::Base
486486
self.table_name = "books"
487487

488488
belongs_to :author
489-
enum last_read: { unread: 0, reading: 2, read: 3, forgotten: nil }
489+
enum :last_read, { unread: 0, reading: 2, read: 3, forgotten: nil }
490490
end
491491

492492
def test_association_enum_works_properly

activerecord/test/cases/associations/has_one_associations_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ class SpecialBook < ActiveRecord::Base
807807
belongs_to :author, class_name: "SpecialAuthor"
808808
has_one :subscription, class_name: "SpecialSubscription", foreign_key: "subscriber_id"
809809

810-
enum status: [:proposed, :written, :published]
810+
enum :status, [:proposed, :written, :published]
811811
end
812812

813813
class SpecialAuthor < ActiveRecord::Base

activerecord/test/cases/attribute_methods_test.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1381,7 +1381,8 @@ class ChildWithDeprecatedBehaviorResolved < ClassWithDeprecatedAliasAttributeBeh
13811381
self.table_name = "books"
13821382

13831383
attribute :status, :string
1384-
enum status: {
1384+
1385+
enum :status, {
13851386
pending: "0",
13861387
completed: "1",
13871388
}

0 commit comments

Comments
 (0)