lib/simplest_status/model_methods.rb
module SimplestStatus
class ModelMethods
attr_reader :model, :statuses
def initialize(model, statuses)
@model = model
@statuses = statuses
end
def add
define_statuses_accessor_for statuses
populate_statuses
process_each_status
define_status_label_method_for statuses
set_validations_for statuses
end
private
def define_statuses_accessor_for(statuses)
model.send :define_singleton_method, statuses.model_accessor do
instance_variable_get('@' + statuses.model_accessor)
end
end
def populate_statuses
model.send(:instance_variable_set, '@' + statuses.model_accessor, statuses)
end
def process_each_status
statuses.each do |status|
set_constant_for status
define_class_methods_for status, statuses.status_name
define_instance_methods_for status
end
end
def set_constant_for(status)
model.send :const_set, status.constant_name, status.value
end
def define_class_methods_for(status, status_name)
model.send :define_singleton_method, status.symbol do
where(status_name => status.value)
end
end
def define_instance_methods_for(status)
define_predicate(status, statuses.status_name)
define_status_setter(status, statuses.status_name)
end
def define_predicate(status, status_name)
model.send :define_method, "#{status.symbol}?" do
send(status_name) == status.value
end
end
def define_status_setter(status, status_name)
model.send :define_method, status.symbol do
update_attributes(status_name => status.value)
end
end
def define_status_label_method_for(statuses)
model.send :define_method, "#{statuses.status_name}_label" do
self.class.send(statuses.model_accessor).label_for send(statuses.status_name)
end
end
def set_validations_for(statuses)
model.send :validates, statuses.status_name, :presence => true, :inclusion => { :in => statuses.values }
end
end
end