class SupplierEmployeesSettings attr_reader :dictionary, :employee_ids, :supplier def initialize(supplier) @supplier = supplier @dictionary = supplier.employee_settings_storage || {} @employee_ids = supplier.employee_ids || [] end def for_employee(employee_id) employee_id = employee_id.id if employee_id.is_a?(Employee) if employee_ids.include? employee_id SupplierEmployeeSettings.new(self, employee_id, dictionary[employee_id]) else SupplierEmployeeSettings::NullObject.new end end def [](val) val = val.to_s if dictionary[val].is_a? SettingsPersistor dictionary[val] else dictionary[val] = SettingsPersistor.new(self, dictionary[val]) end end def persist supplier.employee_settings_storage = dictionary end def method_missing(m, *args) dictionary.send(m, *args) end class SettingsPersistor < Hash attr_reader :all_employees_settings def initialize(all_employees_settings, options = {}) @all_employees_settings = all_employees_settings self.replace options if options.is_a? Hash end def []=(*args) super all_employees_settings.persist end end class SupplierEmployeeSettings delegate :as_json, :to_json, to: :settings DEFAULTS = { 'manager' => false } attr_reader :id, :settings, :all_employees_settings class NullObject < ::NullObject end def initialize(all_employees_settings, employee_id, settings = {}) @all_employees_settings = all_employees_settings @id = employee_id @settings = DEFAULTS.merge(settings || {}) end def manager? settings['manager'] end def is_manager! all_employees_settings[id]['manager'] = true end end end