thetron / mongoid-enum

Sweet enum sugar for your Mongoid documents
MIT License
117 stars 165 forks source link

Scopes can silently override existing methods #44

Open mmindenhall opened 7 years ago

mmindenhall commented 7 years ago

In the process of converting a project from using symbolize/mongoid to mongoid-enum, I had a model that declares the following enum:

    # old symbolize/mongoid declaration
    # symbolize :status, in: [:new, :success, :fail], default: :new

    # new mongoid-enum declaration
    enum :status, [:new, :success, :fail]

The enum declaration creates scope methods for the enum values:

MyModel.new # => Mongoid::Criteria
MyModel.success # => Mongoid::Criteria
MyModel.fail # => Mongoid::Criteria

So now mongoid-enum has overridden the new method, which blows up calls to MyModel.create or MyModel.create!.

There are a couple of ways this can be fixed (ideally, both could be implemented).

  1. Add a new option to disable scopes for an enum:

        enum :status, [:new, :success, :fail], :scopes => false
  2. Add a scope method prefix configuration option to avoid namespace collisions (e.g., scope_ or s_ for brevity):
module Mongoid
  module Enum
    class Configuration
      attr_accessor :field_name_prefix
      attr_accessor :scope_method_prefix

      def initialize
        self.field_name_prefix = "_"
        self.scope_method_prefix = "s_"
      end
    end

    def self.configuration
      @configuration ||= Configuration.new
    end

    def self.configure
      yield(configuration) if block_given?
    end
  end
end