Skip to content

Instantly share code, notes, and snippets.

@stefanvermaas
Last active Sep 28, 2021
Embed
What would you like to do?
# frozen_string_literal: true
require 'active_support'
require 'forwardable'
module ActiveRecord
class Base
def self.method_missing(method_name, *args, &block)
if relation.respond_to?(method_name)
relation.send(method_name, args, &block)
else
super
end
end
def self.respond_to_missing?(method_name, include_private = false)
relation.respond_to?(method_name) || super
end
def self.relation
return @relation if defined?(@relation)
@relation = Relation.new(self)
end
def self.all
# Here the actual fetching of resources happens. Might want to cache the result.
# For example: `@all = relation.where_clauses.map { |result| self.new(id: rand(0..100)) }`.
relation.where_clauses.map { |result| self.new(id: rand(0..100)) }
end
end
module QueryMethods
def includes(*fields)
self.include_values += build_include_values(*fields)
self
end
def where(opts)
self.where_clauses += build_where_clause(opts)
self
end
private
def build_include_values(fields)
fields
end
def build_where_clause(opts)
[opts]
end
end
class Relation
extend Forwardable
include Enumerable, QueryMethods
attr_accessor :include_values, :where_clauses
def_delegators :all, :inspect, :length, :to_s
def initialize(klass)
@klass = klass
@include_values = []
@where_clauses = []
end
def each(&block)
block.call(@klass.all)
end
private
def all
@klass.all
end
end
end
class SalesOrder < ActiveRecord::Base
attr_accessor :id
def initialize(id:)
@id = id
end
end
p SalesOrder.includes(:id, :name).where(id: 100).where(name: 'test')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment