Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - ArgumentError in using ActiveRecord::Enum

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.

like image 997
Gokul Avatar asked Dec 18 '17 06:12

Gokul


4 Answers

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?
like image 189
Kaushlendra Tomar Avatar answered Nov 18 '22 10:11

Kaushlendra Tomar


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]]
like image 37
Wasif Hossain Avatar answered Nov 18 '22 10:11

Wasif Hossain


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

like image 32
Shani Avatar answered Nov 18 '22 09:11

Shani


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
like image 1
kcamel Avatar answered Nov 18 '22 10:11

kcamel