KatPadi's Point

Ruby Gem That Makes Your Model Activatable

Aktibibo is a simple Ruby gem that makes your model activatable. It allows an ActiveRecord model to be declared as “activatable” thus providing scopes for querying and filtering objects. Of course, the module adds convenience methods for setting an instance as active, inactive or deactivated. As an additional feature, it also saves the activation and deactivation dates because it uses datetime DB columns instead of just simple boolean flags.

Link to gem: https://rubygems.org/gems/aktibibo

So the codes…

Disclaimer: I created this for fun, practice and future convenience when I need an “activatable” module. This is basic.

Anyway, you can check the source code here: https://github.com/katpadi/aktibibo

I just need to explain some parts of the code because my blog is telling me that I am below the minimum recommended 300 words.

module Aktibibo
module Activatable
extend ActiveSupport::Concern

module ClassMethods
def activatable
scope :inactive, -> { where(activated_at: nil) }
scope :active, -> { where.not(activated_at: nil) }
scope :deactivated, -> { where.not(deactivated_at: nil) }
end
end

def inactive?
activated_at.blank? && deactivated_at.blank?
end

def active?
activated_at.present? && deactivated_at.blank?
end

def deactivated?
deactivated_at.present?
end

def activate
return if active?
self.activated_at = Time.now.utc if inactive?
self.deactivated_at = nil if deactivated?
save
end

def activate!
fail Errors::AlreadyActivated if active?
self.activated_at = Time.now.utc if inactive?
self.deactivated_at = nil if deactivated?
self.save!
end

def deactivate
return if deactivated?
self.deactivated_at = Time.now.utc
save
end

def deactivate!
fail Errors::AlreadyDeactivated if deactivated?
self.deactivated_at = Time.now.utc
self.save!
end
end
end

First things first… the extend ActiveSupport::Concern means we’re creating a mixin.

The module ClassMethods block basically defines Class methods in itself. For example, in my code above, it adds the declaration of a model to make it “activatable” and it includes the scopes. This function tells the model class that it can query objects by using the defined scopes. Note that you can do a lot of things here other than scopes. But since this is just a simple gem, it’s just doing that.

Going back to the code, everything that is defined within the module and out of the module ClassMethods block will be instance methods. They will be executed within the context of the instance the model that is including the module.

Le setup

  1. Create the necessary columns using a migration: rails generate migration add_activated_at_to_foo activated_at:datetime deactivated_at:datetime
  2. Define that your model is “activatable” by adding the ff in your model:
    class Foo < ActiveRecord::Base
    activatable
    end
    Foo model

    Usage

    Let’s say that an instance foo is available.

    Methods

    foo.activate
    foo.deactivate

    Non-bang methods will just return nil (gracefully) if an already active instance is activated. Same goes for deactivate.

    Methods with a bang!

    foo.activate!
    foo.deactivate!


    Bang methods, on the other hand, will raise AktibiboError if activated while active or deactivated while deactivated/inactive.

    Raising “AktibiboError” is weird. I know.

    Boolean methods

    foo.active?
    foo.deactivated?
    foo.inactive?

    Scopes

    Foo.inactive # Returns all the inactive foos
    Foo.activated # Returns all the active foos
    Foo.deactivated # Returns all the deactivated foos

    Datetimes

    foo.activated_at  # Fri, 29 Apr 2016 08:29:03 UTC  00:00
    foo.deactivated_at # nil

    Link to gem: https://rubygems.org/gems/aktibibo

    Leave a Reply to Anonymous Cancel reply

    Your email address will not be published. Required fields are marked *