module Olivander module Resources module ModelRegistry mattr_accessor :global_registry module Registry extend ActiveSupport::Concern class_methods do attr_accessor :_registry_hash attr_accessor :_registering def register(model, &block) self._registry_hash ||= {} self._registering = ensure_registry_for(model) instance_exec(&block) _registering.make_datatable_classes self._registering = nil # Rails.logger.debug _registry_hash end def entry_for(model) _registry_hash[model] end def ensure_registry_for(model) _registry_hash[model] ||= RegisteredModel.new(model) end def field_layout(layouts = [:show, :form]) layouts = [*layouts] # ensure it's an array field_layout = block_given? ? yield : :all layouts.each do |layout| Rails.logger.debug "setting layout for #{_registering}[#{layout}]" _registering.add_layout(layout, field_layout) end end def add_datatable(view = nil, &block) _registering.add_datatable(view, DatatableDef.new(_registering, &block)) end def render_fields(field_list, with_format: :string) _registering.render_fields(field_list, with_format) end end end class DatatableDef attr_accessor :model, :blocks, :datatable_class, :block def initialize(model, &block) Rails.logger.info "making new datatable" Rails.logger.info block.source self.model = model self.blocks = {} # instance_exec(&block) if block_given? self.block = block end def datatable(sym) blocks[:datatable] = Proc.new{ datatable do model.send(sym) end } end def collection(sym) blocks[:collection] = Proc.new{ collection do model.send(sym) end } end def filters(sym) blocks[:filters] = Proc.new{ model.send(sym) } end def charts(sym) blocks[:charts] = Proc.new{ model.send(sym) } end def make_class(key) # return datatable_class unless datatable_class.nil? # ensure_blocks name_key = key == :index ? '' : key name = [model.name.demodulize, name_key, 'Datatable'].join blocks = self.blocks block = self.block klass = Class.new(Olivander::Datatable) do puts 'stuff' # blocks.values.each do |block| # puts 'this is a block' # puts block.source # instance_eval(block.source) # binding.pry # instance_exec(&block) # end # collection do # Erp::Rate.all # end instance_exec(&block) end module_name = model.name.deconstantize constantized_module = module_name.constantize constantized_module.send(:remove_const, name) if constantized_module.const_defined?(name) self.datatable_class = constantized_module.const_set(name, klass) end def ensure_blocks blocks[:collection] ||= Proc.new{ model.all } end end class RegisteredModel attr_accessor :fields, :layouts, :datatables, :name, :model def initialize(model) self.model = model set_fields self.layouts = {} self.datatables = {} self.name = model.name end def to_s name end def inspect name end def add_layout(key, layout) layout = [[2, fields]] if layout == :all layouts[key] = layout end def layout(key) layouts[key] || add_layout(key, :all) end def add_datatable(key, datatable_def) Rails.logger.info "adding datatable #{key}" datatables[key || :index] = datatable_def # binding.pry end def datatable(key) datatables[key] || add_datatable(key, DatatableDef.new(self)) end def make_datatable_classes datatables.each do |key, dt_def| dt_def.make_class(key) end end def render_fields(field_list, with_format) field_list.each do |field| fields[field].render_as = with_format end end private def set_fields self.fields = {} if model.respond_to?(:columns) model.columns.map{ |x| RegisteredField.new(x) }.each do |field| fields[field.key] = field end end end end class RegisteredField attr_accessor :key, :ar_def, :dt_def, :render_as def to_s key end def inspect key end def initialize(ar_def) self.key = ar_def.name.to_sym self.ar_def = ar_def self.render_as = ar_def.type self.dt_def = {} end end class DefaultModelRegistry include Registry ::Olivander::Resources::ModelRegistry.global_registry = Olivander::Resources::ModelRegistry::DefaultModelRegistry end end end end