Skip to content

Instantly share code, notes, and snippets.

@nukturnal

nukturnal/report.rb

Forked from bgreenlee/report.rb
Created Dec 31, 2018
Embed
What would you like to do?
Displays a mysql-style report for an array of ActiveRecord objects. Stick it in your .irbrc.
# mysql-style output for an array of ActiveRecord objects
#
# Usage:
# report(records) # displays report with all fields
# report(records, :field1, :field2, ...) # displays report with given fields
#
# Example:
# >> report(records, :id, :amount, :created_at)
# +------+-----------+--------------------------------+
# | id | amount | created_at |
# +------+-----------+--------------------------------+
# | 8301 | $12.40 | Sat Feb 28 09:20:47 -0800 2009 |
# | 6060 | $39.62 | Sun Feb 15 14:45:38 -0800 2009 |
# | 6061 | $167.52 | Sun Feb 15 14:45:38 -0800 2009 |
# | 6067 | $12.00 | Sun Feb 15 14:45:40 -0800 2009 |
# | 6059 | $1,000.00 | Sun Feb 15 14:45:38 -0800 2009 |
# +------+-----------+--------------------------------+
# 5 rows in set
#
def report(items, *fields)
# find max length for each field; start with the field names themselves
fields = items.first.class.column_names unless fields.any?
max_len = Hash[*fields.map {|f| [f, f.to_s.length]}.flatten]
items.each do |item|
fields.each do |field|
len = item.read_attribute(field).to_s.length
max_len[field] = len if len > max_len[field]
end
end
border = '+-' + fields.map {|f| '-' * max_len[f] }.join('-+-') + '-+'
title_row = '| ' + fields.map {|f| sprintf("%-#{max_len[f]}s", f.to_s) }.join(' | ') + ' |'
puts border
puts title_row
puts border
items.each do |item|
row = '| ' + fields.map {|f| sprintf("%-#{max_len[f]}s", item.read_attribute(f)) }.join(' | ') + ' |'
puts row
end
puts border
puts "#{items.length} rows in set\n"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment