Skip to content

Instantly share code, notes, and snippets.

@MarceloCajueiro
Created September 3, 2012 13:02
Show Gist options
  • Save MarceloCajueiro/3609182 to your computer and use it in GitHub Desktop.
Save MarceloCajueiro/3609182 to your computer and use it in GitHub Desktop.

Given that I have:

class Status < EnumerateIt::Base
  associate_values :active, :inactive
end

And I have a product model that has status.

Today if I want to change only the status value I do:

product = Product.first
product.active!
product.save

But in my way view I think that will be more clear the follow example:

product = Product.first
product.active! # product.update_attribute(:status, Status::Active)

# or
product.active # product.status = Status::Active
product.save

In the @nohup systems we have several rules that change only an enumeration attribute and to avoid the actual approach we subscribe the method! that to me make more sense.

What do you think about this?

@MarceloCajueiro
Copy link
Author

I think more and this couldn't be a good ideia because of the dependency with active_active record.

I will try to find other way.

@cassiomarques
Copy link

I also see the problem of coupling with AR. Maybe this could be configurable some way, I don't know.

At the same time, if you need to persist the new status right after changing it using the mutator method, you could create a new method at your model. This way EnumerateIt won't depend on AR and we can have this behavior customizable per model class.

What do you think?

@MarceloCajueiro
Copy link
Author

Is an option, but I want it in a global form without define it in each model with enumeration.

We can do something like:

# config/initializers/enumerate_it.rb


module EnumerateIt
  module CustomClassMethods
    include ClassMethods

    def create_mutator_methods(klass, attribute_name)
      class_eval do
        klass.enumeration.each_pair do |key, values|
          define_method "#{key}!" do
            self.update_column(:"#{attribute_name}", values.first)
          end

          define_method "#{key}" do
            self.send "#{attribute_name}=", values.first
          end
        end
      end
    end
  end

  def self.included(receiver)
    receiver.class_attribute :enumerations, :instance_writer => false, :instance_reader => false
    receiver.enumerations = {}

    receiver.extend CustomClassMethods
  end
end

ActiveSupport.on_load(:active_record) do
  include EnumerateIt
end

Or adding a configuration to the gem like you said.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment