module LookUp def lookup(table) model = table.to_s.camelize.constantize foreign_key = table.to_s.downcase.concat('_id') # getter define_method table.to_s do model.try(:find_by_id, read_attribute(foreign_key.to_sym)) end # setter that accepts :value, 'value' or Value object define_method "#{table.to_s}=" do |value| record = value.try(:is_a?, model) ? value : model.try(:find_or_create_by_name, value.to_s) write_attribute(foreign_key, record.id) unless respond_to?("#{record.name.downcase}?".to_sym) instance_exec(self) do |instance| instance.class.send(:define_method,"#{record.name.downcase}?") do instance.send(foreign_key.to_sym) == record.id end end self.class.singleton_class.instance_eval do define_method record.name.downcase.pluralize do includes(table.to_s.to_sym).where(:status_id => record.id ) end end end end # getter for dirty attributes define_method "#{table.to_s}_was" do model.try(:find_by_id, attribute_was(foreign_key)) end model.all.each do |record| # returns collection of each lookup object eg Model.todos define_singleton_method record.name.downcase.pluralize do includes(table.to_s.to_sym).where(foreign_key.to_sym => record.id ) end # adds boolean methods to check whether an object is of lookup type eg. @instance.pending? define_method "#{record.name.downcase}?" do send(foreign_key.to_sym) == record.id end end end end class ActiveRecord::Base extend LookUp end