Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cop to detect deprecated enums with keyword arguments #1238

Closed
yahonda opened this issue Feb 14, 2024 · 3 comments · Fixed by #1336
Closed

Cop to detect deprecated enums with keyword arguments #1238

yahonda opened this issue Feb 14, 2024 · 3 comments · Fixed by #1336
Labels
feature request Request for new functionality

Comments

@yahonda
Copy link

yahonda commented Feb 14, 2024

Is your feature request related to a problem? Please describe.

Rails main branch raises DEPRECATION WARNING: Defining enums with keyword arguments is deprecated and will be removed in Rails 7.3 since rails/rails#50987 I'd like have some cops to detect and address these warnings.

Describe the solution you'd like

I'd like have some cops to detect and auto-correct these warnings.

Describe alternatives you've considered

Follow the warning and fix each enum definition manually.

DEPRECATION WARNING: Defining enums with keyword arguments is deprecated and will be removed
in Rails 7.3. Positional arguments should be used instead:

enum :status, [:active, :archived]
 (called from <class:Conversation> at foo.rb:34)

Additional context

Here is a sample ruby script to reproduce this warning.

  • foo.rb
require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  gem "rails", github: "rails/rails", branch: "main"
  gem "sqlite3"
end

require "active_record"
require "minitest/autorun"
require "logger"

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :conversations, force: true do |t|
    t.column :status, :integer, default: 0
  end
end

# good
# enum :status, [ :active, :archived ]
# bad
# enum status: [ :active, :archived ]

class Conversation < ActiveRecord::Base
  enum status: [ :active, :archived ]
end

class BugTest < Minitest::Test
  def test_association_stuff
    conversation = Conversation.create!
    assert conversation.active?
    refute conversation.archived?
  end
end
  • Run the foo.rb
$ ruby foo.rb
Fetching https://github.com/rails/rails.git
Fetching gem metadata from https://rubygems.org/..........
Resolving dependencies...
-- create_table(:conversations, {:force=>true})
D, [2024-02-14T13:48:22.489739 #201147] DEBUG -- :    (2.0ms)  DROP TABLE IF EXISTS "conversations"
D, [2024-02-14T13:48:22.490110 #201147] DEBUG -- :    (0.1ms)  CREATE TABLE "conversations" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "status" integer DEFAULT 0)
   -> 0.0089s
D, [2024-02-14T13:48:22.491160 #201147] DEBUG -- :    (0.1ms)  CREATE TABLE "schema_migrations" ("version" varchar NOT NULL PRIMARY KEY)
D, [2024-02-14T13:48:22.492450 #201147] DEBUG -- :    (0.1ms)  CREATE TABLE "ar_internal_metadata" ("key" varchar NOT NULL PRIMARY KEY, "value" varchar, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL)
D, [2024-02-14T13:48:22.508765 #201147] DEBUG -- :   ActiveRecord::InternalMetadata Load (1.0ms)  SELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = ? ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1  [[nil, "environment"]]
D, [2024-02-14T13:48:22.509110 #201147] DEBUG -- :   ActiveRecord::InternalMetadata Create (0.1ms)  INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ('environment', 'development', '2024-02-14 04:48:22.508832', '2024-02-14 04:48:22.508838') RETURNING "key"
DEPRECATION WARNING: Defining enums with keyword arguments is deprecated and will be removed
in Rails 7.3. Positional arguments should be used instead:

enum :status, [:active, :archived]
 (called from <class:Conversation> at foo.rb:32)
Run options: --seed 37140

# Running:

D, [2024-02-14T13:48:22.615934 #201147] DEBUG -- :   TRANSACTION (0.0ms)  begin transaction
D, [2024-02-14T13:48:22.616119 #201147] DEBUG -- :   Conversation Create (0.3ms)  INSERT INTO "conversations" DEFAULT VALUES RETURNING "id"
D, [2024-02-14T13:48:22.617499 #201147] DEBUG -- :   TRANSACTION (0.0ms)  commit transaction
.

Finished in 0.009117s, 109.6865 runs/s, 219.3730 assertions/s.
1 runs, 2 assertions, 0 failures, 0 errors, 0 skips
$
@yahonda
Copy link
Author

yahonda commented Feb 14, 2024

Here are the example of good and bad ones.

  • Good one
class Conversation < ActiveRecord::Base
  enum :status, [ :active, :archived ]
end
  • Bad one
class Conversation < ActiveRecord::Base
  enum status: [ :active, :archived ]
end

maxprokopiev added a commit to maxprokopiev/rubocop-rails that referenced this issue Feb 16, 2024
Defining enums with keyword arguments is deprecated
and will be removed in Rails 7.3.
maxprokopiev added a commit to maxprokopiev/rubocop-rails that referenced this issue Feb 16, 2024
Defining enums with keyword arguments is deprecated
and will be removed in Rails 7.3.
maxprokopiev added a commit to maxprokopiev/rubocop-rails that referenced this issue Feb 16, 2024
Defining enums with keyword arguments is deprecated
and will be removed in Rails 7.3.
@koic koic added the feature request Request for new functionality label Feb 28, 2024
@yahonda
Copy link
Author

yahonda commented Feb 29, 2024

This good syntax like enum :status, [ :active, :archived ] has been introduced since Rails 7.0 via rails/rails#41328 . Using this syntax for Rails 6.1 raises ``enum': wrong number of arguments (given 2, expected 1) (ArgumentError)`

  • foo1238_61.rb
require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  gem "rails", "~> 6.1.0"
  gem "sqlite3"
end

require "active_record"
require "minitest/autorun"
require "logger"

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :conversations, force: true do |t|
    t.column :status, :integer, default: 0
  end
end

# good
# enum :status, [ :active, :archived ]
# bad
# enum status: [ :active, :archived ]

class Conversation < ActiveRecord::Base
  enum :status, [ :active, :archived ]
end

class BugTest < Minitest::Test
  def test_association_stuff
    conversation = Conversation.create!
    assert conversation.active?
    refute conversation.archived?
  end
end
$
$ ruby foo1238_61.rb 
Fetching gem metadata from https://rubygems.org/...........
Resolving dependencies...
/home/yahonda/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-6.1.7.7/lib/active_support/message_verifier.rb:3: warning: base64 was loaded from the standard library, but will no longer be part of the default gems since Ruby 3.4.0. Add base64 to your Gemfile or gemspec. Also contact author of activesupport-6.1.7.7 to add base64 into its gemspec.
/home/yahonda/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-6.1.7.7/lib/active_support/dependencies.rb:332: warning: bigdecimal was loaded from the standard library, but will no longer be part of the default gems since Ruby 3.4.0. Add bigdecimal to your Gemfile or gemspec. Also contact author of activesupport-6.1.7.7 to add bigdecimal into its gemspec.
/home/yahonda/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-6.1.7.7/lib/active_support/dependencies.rb:332: warning: mutex_m was loaded from the standard library, but will no longer be part of the default gems since Ruby 3.4.0. Add mutex_m to your Gemfile or gemspec. Also contact author of activesupport-6.1.7.7 to add mutex_m into its gemspec.
-- create_table(:conversations, {:force=>true})
D, [2024-03-01T08:10:27.313045 #31274] DEBUG -- :    (0.7ms)  SELECT sqlite_version(*)
D, [2024-03-01T08:10:27.313384 #31274] DEBUG -- :    (0.0ms)  DROP TABLE IF EXISTS "conversations"
D, [2024-03-01T08:10:27.313743 #31274] DEBUG -- :    (0.1ms)  CREATE TABLE "conversations" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "status" integer DEFAULT 0)
   -> 0.0053s
D, [2024-03-01T08:10:27.332203 #31274] DEBUG -- :    (0.1ms)  CREATE TABLE "ar_internal_metadata" ("key" varchar NOT NULL PRIMARY KEY, "value" varchar, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL)
D, [2024-03-01T08:10:27.340223 #31274] DEBUG -- :   ActiveRecord::InternalMetadata Load (1.2ms)  SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = ? LIMIT ?  [["key", "environment"], ["LIMIT", 1]]
D, [2024-03-01T08:10:27.343119 #31274] DEBUG -- :   TRANSACTION (0.0ms)  begin transaction
D, [2024-03-01T08:10:27.343314 #31274] DEBUG -- :   ActiveRecord::InternalMetadata Create (0.1ms)  INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["key", "environment"], ["value", "development"], ["created_at", "2024-02-29 23:10:27.342793"], ["updated_at", "2024-02-29 23:10:27.342793"]]
D, [2024-03-01T08:10:27.343453 #31274] DEBUG -- :   TRANSACTION (0.0ms)  commit transaction
/home/yahonda/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activerecord-6.1.7.7/lib/active_record/enum.rb:158:in `enum': wrong number of arguments (given 2, expected 1) (ArgumentError)
        from foo1238_61.rb:32:in `<class:Conversation>'
        from foo1238_61.rb:31:in `<main>'
$

@yahonda
Copy link
Author

yahonda commented Feb 29, 2024

This good syntax like enum :status, [ :active, :archived ] works as expected for Rails 7.0.z

  • foo1238_70.rb
$ more foo1238_70.rb 
require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  gem "rails", "~> 7.0.0"
  gem "sqlite3"
end

require "active_record"
require "minitest/autorun"
require "logger"

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :conversations, force: true do |t|
    t.column :status, :integer, default: 0
  end
end

# good
# enum :status, [ :active, :archived ]
# bad
# enum status: [ :active, :archived ]

class Conversation < ActiveRecord::Base
  enum :status, [ :active, :archived ]
end

class BugTest < Minitest::Test
  def test_association_stuff
    conversation = Conversation.create!
    assert conversation.active?
    refute conversation.archived?
  end
end
$ ruby foo1238_70.rb
Fetching gem metadata from https://rubygems.org/...........
Resolving dependencies...
/home/yahonda/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.0.8.1/lib/active_support/message_verifier.rb:4: warning: base64 was loaded from the standard library, but will no longer be part of the default gems since Ruby 3.4.0. Add base64 to your Gemfile or gemspec. Also contact author of activesupport-7.0.8.1 to add base64 into its gemspec.
/home/yahonda/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.0.8.1/lib/active_support/core_ext/object/json.rb:5: warning: bigdecimal was loaded from the standard library, but will no longer be part of the default gems since Ruby 3.4.0. Add bigdecimal to your Gemfile or gemspec. Also contact author of activesupport-7.0.8.1 to add bigdecimal into its gemspec.
/home/yahonda/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/activesupport-7.0.8.1/lib/active_support/notifications/fanout.rb:3: warning: mutex_m was loaded from the standard library, but will no longer be part of the default gems since Ruby 3.4.0. Add mutex_m to your Gemfile or gemspec. Also contact author of activesupport-7.0.8.1 to add mutex_m into its gemspec.
-- create_table(:conversations, {:force=>true})
D, [2024-03-01T08:14:12.901063 #32048] DEBUG -- :    (0.0ms)  DROP TABLE IF EXISTS "conversations"
D, [2024-03-01T08:14:12.901388 #32048] DEBUG -- :    (0.1ms)  CREATE TABLE "conversations" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "status" integer DEFAULT 0)
   -> 0.0048s
D, [2024-03-01T08:14:12.920747 #32048] DEBUG -- :    (0.1ms)  CREATE TABLE "ar_internal_metadata" ("key" varchar NOT NULL PRIMARY KEY, "value" varchar, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL)
D, [2024-03-01T08:14:12.928217 #32048] DEBUG -- :   ActiveRecord::InternalMetadata Load (0.9ms)  SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = ? LIMIT ?  [["key", "environment"], ["LIMIT", 1]]
D, [2024-03-01T08:14:12.931977 #32048] DEBUG -- :   TRANSACTION (0.0ms)  begin transaction
D, [2024-03-01T08:14:12.932172 #32048] DEBUG -- :   ActiveRecord::InternalMetadata Create (0.1ms)  INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["key", "environment"], ["value", "development"], ["created_at", "2024-02-29 23:14:12.931327"], ["updated_at", "2024-02-29 23:14:12.931327"]]
D, [2024-03-01T08:14:12.932288 #32048] DEBUG -- :   TRANSACTION (0.0ms)  commit transaction
Run options: --seed 13734

# Running:

D, [2024-03-01T08:14:12.959906 #32048] DEBUG -- :   TRANSACTION (0.0ms)  begin transaction
D, [2024-03-01T08:14:12.960012 #32048] DEBUG -- :   Conversation Create (0.0ms)  INSERT INTO "conversations" DEFAULT VALUES
D, [2024-03-01T08:14:12.960120 #32048] DEBUG -- :   TRANSACTION (0.0ms)  commit transaction
.

Finished in 0.003686s, 271.2821 runs/s, 542.5642 assertions/s.
1 runs, 2 assertions, 0 failures, 0 errors, 0 skips
$

koic pushed a commit to koic/rubocop-rails that referenced this issue Aug 22, 2024
Defining enums with keyword arguments is deprecated
and will be removed in Rails 8.0.
koic pushed a commit to koic/rubocop-rails that referenced this issue Aug 22, 2024
Defining enums with keyword arguments is deprecated
and will be removed in Rails 8.0.
koic pushed a commit to koic/rubocop-rails that referenced this issue Aug 23, 2024
Defining enums with keyword arguments is deprecated
and will be removed in Rails 8.0.
koic pushed a commit to koic/rubocop-rails that referenced this issue Aug 23, 2024
Defining enums with keyword arguments is deprecated
and will be removed in Rails 8.0.
koic added a commit that referenced this issue Aug 24, 2024
koic added a commit to koic/rubocop-rails that referenced this issue Sep 12, 2024
Fixes rubocop#1362.

This PR fixes false positives for `Rails/EnumSyntax` when using Ruby 2.7.

The warning shown in rubocop#1238 appears starting from Rails 7.2 (Requires Ruby 3.1+).
On the other hand, if users use Ruby 2.7, the warning reported in rubocop#1362 will be displayed.

Therefore, it would be appropriate to enable this cop only when analyzing Ruby 3.0+.

Nothing will happen when using Ruby 2.7 with Rails 7.0 or Rails 7.1, but the warning in rubocop#1238
will not be displayed either. Meanwhile, in Rails 7.2, which requires Ruby 3.1+, Ruby 2.7 cannot be used, so there is no issue.
koic added a commit to koic/rubocop-rails that referenced this issue Sep 12, 2024
Fixes rubocop#1362.

This PR fixes false positives for `Rails/EnumSyntax` when using Ruby 2.7.

The warning shown in rubocop#1238 appears starting from Rails 7.2 (Requires Ruby 3.1+).
On the other hand, if users use Ruby 2.7, the warning reported in rubocop#1362 will be displayed.

Therefore, it would be appropriate to enable this cop only when analyzing Ruby 3.0+.

Nothing will happen when using Ruby 2.7 with Rails 7.0 or Rails 7.1, but the warning in rubocop#1238
will not be displayed either. Meanwhile, in Rails 7.2, which requires Ruby 3.1+, Ruby 2.7 cannot be used, so there is no issue.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Request for new functionality
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants