【问题标题】:Rails - ArgumentError in using ActiveRecord::EnumRails - 使用 ActiveRecord::Enum 时出现 ArgumentError
【发布时间】:2018-05-31 11:34:38
【问题描述】:

我创建了一个模型Tester 与整数列tester_type 并在模型中声明了枚举变量。

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

尝试为该模型创建/初始化对象时出现以下错误:

ArgumentError:您试图在模型“Tester”上定义一个名为“tester_type”的枚举,但这会生成一个类方法“group”,该方法已由 Active Record 定义。

所以,我尝试将tester_type 更改为type_of_tester,但它会引发同样的错误:

ArgumentError:您试图在模型“Tester”上定义一个名为“type_of_tester”的枚举,但这会生成一个类方法“group”,该方法已由 Active Record 定义。

我已搜索解决方案,发现此错误是ActiveRecord::Enum 类中的常量ENUM_CONFLICT_MESSAGE,但无法找到此问题的原因。

请帮助我。

谢谢。

【问题讨论】:

  • 更改emum的名字,不要使用testers_type这已经被rails使用了。
  • 我尝试将其更改为type_of_tester,但它会引发同样的错误。
  • 你能不能也粘贴那个错误。
  • 已编辑问题

标签: ruby-on-rails activerecord enums ruby-on-rails-5


【解决方案1】:

在这种情况下,如果您想使用枚举,最好将标签重命名为其他名称。这并不是枚举所独有的——许多 Active Record 功能都会为您生成方法,并且通常没有办法选择退出这些生成的方法。

然后将group 更改为another_name

或者你也应该遵循这个

enum :kind, [:junior, :senior, :group], prefix: :kind
band.kind_group?

【讨论】:

    【解决方案2】:

    看看这个。这是您遇到问题的选项组。您可以使用本文中提到的前缀选项

    enum options

    【讨论】:

      【解决方案3】:

      当您需要定义具有相同值的多个枚举时,或者在您的情况下,您可以使用:_prefix:_suffix 选项,以避免与已定义的方法发生冲突。如果传递的值为true,则方法以枚举名称为前缀/后缀。也可以提供自定义值:

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

      在上面的例子中,bang 和 predicate 方法以及相关的作用域现在被相应地添加前缀和/或后缀:

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

      对于你的情况,我的建议是使用类似的东西:

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

      然后您可以将这些作用域用作:

      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]]
      

      【讨论】:

        【解决方案4】:

        指定前缀选项对我有用。

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

        然后使用它:

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

        请注意,可以使用与问题中提供的相同符号来为枚举值指定显式字符串值而不是整数。这使得保存的 db 值更具人类可读性。

        enum tester_type: { junior: 'junior', senior: 'senior', group: 'group' }, _prefix: true
        
        Tester.first.tester_type_senior!
        => true
        Tester.first.tester_type
        

        【讨论】:

          猜你喜欢
          • 2018-02-24
          • 2014-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多