The power of toggle

I don't know if we've been missing out on deliberate API lovin' or that we're becoming dumber every minute because of too much work, or its just the love month? :) ...but we've been missing the power of "toggle".

Toggle is defined as:

any instruction that works first one way and then the other; it turns something on the first time it is used and then turns it off the next time
Needless to say, toggle is very efficient for use with boolean values (defined by either true or false). Let's take a specific scenario:
  create_table "profiles", :force => true do |t|
    t.string   "salutation",            :limit => 8, :default => ""
    t.string   "name",                  :limit => 200, :default => ""
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "themes", :force => true do |t|
    t.integer "profile_id",
    t.string   "name",            :limit => 100, :default => ""
    t.boolean "primary",        :default => false
  end

So, there are multiple themes per profile. You should get at least that part. Your boolean column should always be set to false by default. Either you replace the name of your column to suit that requirement, or write dirtier code. (I.e., instead of have a "public" column all set to true, use "private" column all set to false by default). Now, of course, your associations should be setup properly similar to:

class Profile < ActiveRecord::Base   # filter_chain methods here...   # validations here...   # associations start...   has_many :themes do      def primary       find(:first, :conditions => ["primary = ?", true])
    end
  end
  # associations end...

end

class Theme < ActiveRecord::Base   # filter_chain methods here...   # validations here...   # associations start...   belongs_to :profile   # associations end...   named_scope :current_theme_of, lambda { |profile|     { :conditions => [ "profile_id = ? and primary = ?", profile.id, true ] }
  }
end

Of course, there would be several records for the Theme table that will belong to a profile. You will offer a checkbox on every create and update of the themes of a particular profile, but how do you ensure that there will only be one primary theme set for each profile record?

This is dirty: (KIDS, DO NOT TRY THIS AT HOME)

class Theme < ActiveRecord::Base   # filter_chain methods here...   after_save :verify_unique_primary_theme   # validations here...   # associations start...   belongs_to :profile   # associations end...   named_scope :current_theme_of, lambda { |profile|     { :conditions => [ "profile_id = ? and primary = ?", profile.id, true ] }
  }

  def verify_unique_primary_theme
    # get all themes by this profile 
    # set all their primary value to false
    # set this new one's primary value to true
  end
end

Man, I wouldn't bet on a quick update on a profile whose set of themes would be more than hundreds, or even thousands! This, of course, is always worth a try:

class Theme < ActiveRecord::Base   # filter_chain methods here...   # validations here...   # associations start...   belongs_to :profile   # associations end...   named_scope :current_theme_of, lambda { |profile|     { :conditions => [ "profile_id = ? and primary = ?", profile.id, true ] }
  }

  def primary?
    primary
  end

  def validate
    #ensure that primary true is for one record only
    if primary? and !profile.themes.primary.nil?
      #toggle the old primary theme of this said profile
      profile.themes.primary.toggle!(:primary)
    end
  end

end

Simple, yet it works! Each time another theme gets toggled to be the primary theme, you only need to make two writes to your database:

  1. Save your new item
  2. Flip the old primary to false
PS: I did write messy code on purpose to illustrate what I meant for this post.

I hope this toggle magic works for you too the next time you think about boolean switches!

:)