Skip to content

Instantly share code, notes, and snippets.

@ehrenmurdick
Last active September 13, 2023 19:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ehrenmurdick/efe166f260906c422916fbf5e224381e to your computer and use it in GitHub Desktop.
Save ehrenmurdick/efe166f260906c422916fbf5e224381e to your computer and use it in GitHub Desktop.
Make ActiveRecord style queries using block syntax
class Query
attr_accessor :mappings
attr_accessor :filters
def initialize
@mappings = []
@filters = []
end
class ConditionProxy
def initialize(q)
@q = q
end
def method_missing(name, *args, &block)
@name = name
self
end
def <(thing)
@q.filters << "#{@name} < #{thing}"
@q
end
end
class MapProxy
def initialize(q)
@q = q
end
def method_missing(name, *args, &block)
@q.mappings << name
@q
end
end
def where(&block)
block.call(ConditionProxy.new(self))
end
def map(&block)
block.call(MapProxy.new(self))
end
def to_sql
"SELECT #{@mappings.join(', ')} FROM table WHERE #{filters.join(' AND ')};"
end
end
puts '=' * 80
q = Query.new
q.where { |p| p.amount < 32 }.map(&:user_id)
p q
p q.to_sql
##<Query:0x00005622190d6560 @mappings=[:user_id], @filters=["amount < 32"]>
#"SELECT user_id FROM table WHERE amount < 32;"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment