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

Open
yahonda opened this issue Feb 14, 2024 · 3 comments
Open

Cop to detect deprecated enums with keyword arguments #1238

yahonda opened this issue Feb 14, 2024 · 3 comments
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
$

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

No branches or pull requests

2 participants