# frozen_string_literal: true module WCC::Media::ActiveRecordShim def self.included(base) base.public_send :include, InstanceMethods base.extend ClassMethods end module InstanceMethods def attributes raw.keys.each_with_object({}) do |key, h| next unless respond_to?(key) val = public_send(key) h[key] = if val.is_a? Array val.map { |v| v.respond_to?(:to_h) ? v.to_h : v } else val.respond_to?(:to_h) ? val.to_h : val end end end end module ClassMethods def active_record_shim(&block) builder = ShimBuilder.new builder.instance_eval(&block) builder.apply(self) self end def find(id, **params) WCC::Media::Client.default.public_send(endpoint).find(id, **params) end def find_all(**filters) WCC::Media::Client.default.public_send(endpoint).list(filters) end def find_by(**filters) raise ArgumentError, 'You must provide at least one filter' if filters.empty? find_all(filters).first end def model_name ActiveModel::Name.new(self, nil, name) end def table_name endpoint end def unscoped yield end def find_in_batches(options, &block) options = options ? options.dup : {} batch_size = options.delete(:batch_size) || 1000 filter = { limit: batch_size, offset: options.delete(:start) || 0 } find_all(filter).each_slice(batch_size, &block) end def where(**conditions) # TODO: return a Query object that implements more of the ActiveRecord query interface # https://guides.rubyonrails.org/active_record_querying.html#conditions find_all(conditions) end end class ShimBuilder def apply(klass) filters = (@filters || []).freeze endpoint = @endpoint || klass.name.split('::').last.downcase key = @key || klass.name.split('::').last.downcase klass.instance_eval do define_singleton_method(:filters) { filters } define_singleton_method(:endpoint) { endpoint } define_singleton_method(:key) { key } end end %i[filters endpoint key].each do |att| class_eval <<-CODE, __FILE__, __LINE__ + 1 def #{att}(value); # def filters(value) @#{att} = value; # @filters = value end # end CODE end end end