Rails - ArgumentError in using ActiveRecord::Enum
Asked Answered
S

4

6

I have created a model Tester with integer column tester_type and declared enum variable in the model.

class Tester < ApplicationRecord
  enum tester_type: { junior: 0, senior: 1, group: 2 }
end

I am getting below error while trying to create / initialize an object for that model:

ArgumentError: You tried to define an enum named "tester_type" on the model "Tester", but this will generate a class method "group", which is already defined by Active Record.

So, I tried changing tester_type to type_of_tester but it throws same error:

ArgumentError: You tried to define an enum named "type_of_tester" on the model "Tester", but this will generate a class method "group", which is already defined by Active Record.

I have searched for the solution and I found this error was a constant ENUM_CONFLICT_MESSAGE in ActiveRecord::Enum class but, cannot able to find the cause of this problem.

Please help me.

Thanks.

Statue answered 18/12, 2017 at 6:26 Comment(4)
change the name of emum, don't use testers_type this is already used by rails.Phyliciaphylis
I tried changing it to type_of_tester but it throws same error.Statue
can you also paste that error.Phyliciaphylis
Edited questionStatue
P
6

In this case, if you want to use enum, you are probably better off renaming your label to something else. This is not unique to enums – a lot of Active Record features generates methods for you and usually there aren't ways to opt-out of those generated methods.

then change group to another_name

OR you should follow this also

enum :kind, [:junior, :senior, :group], prefix: :kind
band.kind_group?
Phyliciaphylis answered 18/12, 2017 at 8:12 Comment(1)
I have the same issue, but when I add the prefix 'application', the error just changes to: "this will generate a instance method "application_Submitted?", which is already defined by another enum." But how? I just created the prefix 'application' a moment ago? How can it be defined by another enum?Palacios
L
5

You can use the :_prefix or :_suffix options when you need to define multiple enums with same values or in your case, to avoid conflict with already defined methods. If the passed value is true, the methods are prefixed/suffixed with the name of the enum. It is also possible to supply a custom value:

class Conversation < ActiveRecord::Base
  enum status: [:active, :archived], _suffix: true
  enum comments_status: [:active, :inactive], _prefix: :comments
end

With the above example, the bang and predicate methods along with the associated scopes are now prefixed and/or suffixed accordingly:

conversation.active_status!
conversation.archived_status? # => false

conversation.comments_inactive!
conversation.comments_active? # => false

For your case, my suggestion would be using something like:

class Tester < ApplicationRecord
  enum tester_type: { junior: 0, senior: 1, group: 2 }, _prefix: :type
end

Then you can use these scopes as:

tester.type_group!
tester.type_group? # => true

Tester.type_group # SELECT "testers".* FROM "testers" WHERE "testers"."tester_type" = $1  [["tester_type", 2]]
# or,
Tester.where(tester_type: :group) # SELECT "testers".* FROM "testers" WHERE "testers"."tester_type" = $1  [["tester_type", 2]]
Lobachevsky answered 18/12, 2017 at 11:0 Comment(0)
P
1

check this out. it is the option group you are having a problem with. You can use prefix option as mentioned in this post

enum options

Phyllotaxis answered 18/12, 2017 at 8:12 Comment(0)
H
1

Specifying a prefix option worked for me.

# models/tester.rb
enum tester_type: { junior: 0, senior: 1, group: 2 }, _prefix: true

And then to use it:

Tester.first.tester_type
=> nil
Tester.first.tester_type_junior!
=> true
Tester.first.tester_type
=> 0

Note that the enum values can be given explicit string values instead of integers, with the same notation provided in the question. Which makes the saved db values more human readable.

enum tester_type: { junior: 'junior', senior: 'senior', group: 'group' }, _prefix: true

Tester.first.tester_type_senior!
=> true
Tester.first.tester_type
Humorist answered 21/7, 2021 at 22:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.