class FilterTable::Factory
def add(method_name, opts = {}, &block)
def add(method_name, opts = {}, &block) if method_name.nil? throw RuntimeError, "Called filter.add for resource #{@resource} with method name nil!" end @connectors[method_name.to_sym] = Connector.new(opts[:field] || method_name, block, opts) self end
def add_accessor(method_name)
def add_accessor(method_name) if method_name.nil? throw RuntimeError, "Called filter.add_delegator for resource #{@resource} with method name nil!" end @accessors.push(method_name) self end
def connect(resource, table_accessor)
def connect(resource, table_accessor) # create the table structure connectors = @connectors struct_fields = connectors.values.map(&:field_name) connector_blocks = connectors.map do |method, c| [method.to_sym, create_connector(c)] end # the struct to hold single items from the #entries method entry_struct = Struct.new(*struct_fields.map(&:to_sym)) do attr_accessor :__filter def to_s # rubocop:disable Lint/NestedMethodDefinition @__filter || super end end unless struct_fields.empty? # the main filter table table = Class.new(Table) { connector_blocks.each do |x| define_method x[0], &x[1] end define_method :new_entry do |hashmap, filter = ''| return entry_struct.new if hashmap.nil? res = entry_struct.new(*struct_fields.map { |x| hashmap[x] }) res.__filter = filter res end } # define all access methods with the parent resource accessors = @accessors + @connectors.keys accessors.each do |method_name| resource.send(:define_method, method_name.to_sym) do |*args, &block| filter = table.new(self, method(table_accessor).call, ' with') filter.method(method_name.to_sym).call(*args, &block) end end end
def create_connector(c)
def create_connector(c) return ->(cond = Show) { c.block.call(self, cond) } if !c.block.nil? lambda { |condition = Show, &cond_block| if condition == Show && !block_given? r = where(nil).get_field(c.field_name) r = r.flatten.uniq.compact if c.opts[:style] == :simple r else where({ c.field_name => condition }, &cond_block) end } end
def initialize
def initialize @accessors = [] @connectors = {} end
def to_s # rubocop:disable Lint/NestedMethodDefinition
def to_s # rubocop:disable Lint/NestedMethodDefinition @__filter || super end