Skip to content

Instantly share code, notes, and snippets.

@Agowan
Last active August 29, 2015 13:58
Show Gist options
  • Save Agowan/9961877 to your computer and use it in GitHub Desktop.
Save Agowan/9961877 to your computer and use it in GitHub Desktop.
A simple way of handling custom sql queries without involving ActiveRecord. (Using postgresql)
# encoding: utf-8
class Context
class Context::Result
def initialize(*args, &block)
args.extract_options!.each do |attr, value|
send("#{attr}=", numeric?(value)) if respond_to?("#{attr}=")
end
block.call(self) if block
end
protected
def numeric?(value)
if value.is_a?(String) && value =~ /^\d*$/
value.to_i
else
value
end
end
end
protected
def select_all(sql)
con.select_all compress(sql)
end
def compress(sql)
sql.squeeze(' ').gsub(/\n/,'').strip
end
def con
ActiveRecord::Base.connection
end
end
# encoding: utf-8
class StatisticsOrder
class Result < Context::Result
attr_accessor :name, :order, :delivered, :paid
end
def each(&block)
items.each(&block)
end
protected
def items
@items ||= select_all(sql).map do |hash|
Result.new hash
end
end
private
def sql
<<-sql
SELECT "sales"."name", COUNT(*),
SUM(CASE "orders"."delivered_at" IS NOT NULL THEN 1 ELSE 0 END) as "delivered",
SUM(CASE "orders"."paid_at" IS NOT NULL THEN 1 ELSE 0 END) AS "paid"
FROM "orders"
JOIN "sales" ON "orders"."sales_id" = "sales"."id"
WHERE "sales"."created_at" > "2014-01-13 12:54:00"
GROUP BY "sales"."name"
sql
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment