Rails error: instance method already defined by another enum but there are no repeats

Viewed 1499

I am trying to debug some errors that appear when I run bundle exec rake tasks.

ArgumentError: You tried to define an enum named "catalogue" on the model "CollectionContext", but this will generate a instance method "museum?", which is already defined by another enum.

There are a number of questions on SO relating to this problem but all seem to come down to the use of the same value for different enums within the same model, which can be resolved with the use of _suffix or _prefix.

Here's an excellent explanation of enum usage in Rails https://naturaily.com/blog/ruby-on-rails-enum

In my case I cannot see a duplicate in my model. How can I debug the error further?

class CollectionContext < ActiveRecord::Base
  include Authority::Abilities
  self.authorizer_name = 'ManagedContentAuthorizer'

  has_many :context_sets, inverse_of: :collection_context
  has_many :museum_collections, through: :context_sets,
                                source: :contextable,
                                source_type: 'MuseumCollection'

  enum catalogue: %i[museum archive library]
  enum vocabulary: {category: 10,
                    collection: 20,
                    concept: 30,
                    event: 40,
                    gallery: 50,
                    material: 60,
                    organisation: 70,
                    people: 80,
                    person: 90,
                    place: 100,
                    style: 110,
                    technique: 120}

  validate :check_multiple

  def check_multiple
    if [identifier, query, query_url].compact.count != 1
      errors[:base] << " cannot set multiple context links"
    end
  end
end

I've now discovered that if I run rake with my rails environment set to TEST, it doesn't show any problems in the console. So it is a development only problem. I have experimented with my gemfile and put all dev only gems into the dev and test group but I still get the error when running rake in dev.

This is my config/development.rb file

# frozen_string_literal: true

Rails.application.configure do
  config.webpacker.check_yarn_integrity = false
  config.cache_classes = false
  config.eager_load = false
  config.consider_all_requests_local = true
  config.action_controller.perform_caching = false
  config.action_mailer.raise_delivery_errors = false
  config.active_support.deprecation = :log
  config.active_record.migration_error = :page_load
  config.assets.debug = true
  config.assets.digest = true
  config.assets.raise_runtime_errors = true
  config.web_console.whitelisted_ips = '10.xxxx'
end
1 Answers

Probably related to having spring or some other such thing running. Try starting dev with DISABLE_SPRING=1 or just removing spring.

Other possibilities include there is a boolean column named museum which is where the museum? method is coming from and some other code we don't see.

In terms of debugging, I'd just open up Rails where the stacktrace is point to the error being raised and use introspection there to see where the detected existing method is defined? sure, there are other tools in the toolbelt like method_added and tracepoint, but I like the 'find where it's raised and do method(:museum?).source_location or some such.

To avoid re-evaluating an enum line in my Rails apps I often will define it for example like

  enum catalogue: %i[museum archive library] unless method_defined?(:museum?)
Related