Skip to content

Instantly share code, notes, and snippets.

@leandroh
Forked from brianjlandau/flagable.rb
Created January 21, 2010 19:38
Show Gist options
  • Save leandroh/283121 to your computer and use it in GitHub Desktop.
Save leandroh/283121 to your computer and use it in GitHub Desktop.
module ActiveRecord
module Acts
module AsFlagable
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def acts_as_flagable(options)
unless flagable?
cattr_accessor :flag_values
self.flag_values = options
after_initialize :set_flag_attributes
before_save :set_flag_mask
attr_accessor *options.keys
options.each_key do |flag|
define_method "#{flag}?" do
(flags & flag_values[flag]) == flag_values[flag]
end
end
include InstanceMethods
end
end
def flagable?
self.included_modules.include?(InstanceMethods)
end
end
module InstanceMethods
private
def set_flag_attributes
flag_values.each_key do |flag|
if self.send("#{flag}?".to_sym)
self.send("#{flag}=".to_sym, true)
else
self.send("#{flag}=".to_sym, false)
end
end
end
def set_flag_mask
self.flags = 0
flag_values.each do |flag, value|
if self.send(flag)
self.flags = self.flags | value
end
end
end
end
end
end
end
ActiveRecord::Base.send(:include, ActiveRecord::Acts::AsFlagable)
class ActiveSupport::TestCase
def self.should_be_flagable(flags)
should 'have a flag_values class method' do
assert_equal flags, self.class.described_type.flag_values
end
should 'be flagable?' do
assert self.class.described_type.flagable?
end
flags.each do|flag, value|
should_have_instance_methods "#{flag}", "#{flag}=", "#{flag}?"
should "correctly set the #{flag} instance variable to true on initiation" do
subject.send("#{flag}=", true)
subject.save!
found_record = self.class.described_type.find(subject.id)
assert found_record.send("#{flag}?")
end
should "correctly set the #{flag} instance variable to false on initiation" do
subject.send("#{flag}=", false)
subject.save!
found_record = self.class.described_type.find(subject.id)
assert !found_record.send("#{flag}?")
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment