Skip to content

Instantly share code, notes, and snippets.

@paul
Created February 25, 2011 16:54
Show Gist options
  • Save paul/844078 to your computer and use it in GitHub Desktop.
Save paul/844078 to your computer and use it in GitHub Desktop.
namespace :schema do
desc "Update doc/schema.dot with database schema"
task :gv => :environment do
@tables = []
Rails.configuration.paths.app.models.paths.each do |path|
Dir[File.join(path, '*.rb')].each do |f|
klass = File.basename(f, '.*').camelize.constantize
if klass < ActiveRecord::Base
begin
klass.columns
rescue Exception => ex
# skip
next
end
@tables << klass if klass < ActiveRecord::Base
end
end
end
data = Erubis::Eruby.new(TEMPLATE).result(binding())
File.open('doc/schema.dot', 'w') do |f|
f.write(data)
end
end
desc "Create a png of the database schema"
task :png => :gv do
`dot -T png -o doc/schema.png doc/schema.dot`
end
end
TEMPLATE = <<-TEMPLATE
digraph Schema {
overlap = false
rankdir = RL
fontsize=12
node [
shape = record
fontsize=12
]
<% @tables.each do |table| %>
<%= table %> [
label = "<%= table %>|\\
<% table.columns.each do |column| %>
<%= column.name.to_s %>: <%= column.type.to_s %>\\l\\
<% end %>
"
];
<% table.reflect_on_all_associations.select { |a| a.macro == :belongs_to }.map(&:class_name).uniq.each do |r| %>
<%= table %> -> <%= r %>;
<% end %>
<% table.reflect_on_all_associations.select { |a| a.macro == :has_and_belongs_to_many }.map(&:class_name).uniq.each do |r| %>
<%= table %> -> <%= r %> [dir=both];
<% end %>
<% end %>
}
TEMPLATE
digraph Schema {
overlap = false
rankdir = RL
fontsize=12
node [
shape = record
fontsize=12
]
Account [
label = "Account|\
id: integer\l\
login: string\l\
des_crypted_password: string\l\
firstname: string\l\
lastname: string\l\
crypted_password: string\l\
salt: string\l\
created_at: datetime\l\
updated_at: datetime\l\
last_login_at: datetime\l\
hex_md5_of_login_realm_password: string\l\
uuid: string\l\
timezone: string\l\
preferred_client_id: integer\l\
"
];
Account -> Client;
Address [
label = "Address|\
id: integer\l\
account_id: integer\l\
name: string\l\
delivery_method: string\l\
identifier: string\l\
uuid: string\l\
created_at: datetime\l\
updated_at: datetime\l\
deleted_at: datetime\l\
"
];
Address -> Account;
Agent [
label = "Agent|\
id: integer\l\
uuid: string\l\
account_id: integer\l\
client_id: integer\l\
host_id: integer\l\
configuration_href: string\l\
notes: text\l\
created_at: datetime\l\
updated_at: datetime\l\
"
];
Agent -> Client;
Agent -> Account;
Agent -> Host;
Client [
label = "Client|\
id: integer\l\
active: integer\l\
name: string\l\
longname: string\l\
parent_id: integer\l\
reseller: boolean\l\
created_at: datetime\l\
updated_at: datetime\l\
uuid: string\l\
"
];
Client -> Client;
EncryptionKey [
label = "EncryptionKey|\
id: integer\l\
private_key_pem: string\l\
slug: string\l\
public_key_pem: string\l\
"
];
Host [
label = "Host|\
id: integer\l\
client_id: integer\l\
hostname: string\l\
active: integer\l\
comments: string\l\
created_at: datetime\l\
updated_at: datetime\l\
uuid: string\l\
"
];
Host -> Client;
HostTag [
label = "HostTag|\
id: integer\l\
name: string\l\
"
];
HostTagging [
label = "HostTagging|\
id: integer\l\
host_id: integer\l\
host_tag_id: integer\l\
"
];
HostTagging -> Host;
HostTagging -> HostTag;
Metric [
label = "Metric|\
id: integer\l\
host_id: integer\l\
metric_type_id: integer\l\
created_at: datetime\l\
uuid: string\l\
"
];
Metric -> MetricType;
Metric -> Host;
MetricFilter [
label = "MetricFilter|\
id: integer\l\
any_or_all: string\l\
created_at: datetime\l\
updated_at: datetime\l\
client_id: integer\l\
purpose: string\l\
uuid: string\l\
deleted_at: datetime\l\
published_at: datetime\l\
"
];
MetricFilter -> Client;
MetricFilterCriterion [
label = "MetricFilterCriterion|\
id: integer\l\
metric_filter_id: integer\l\
target: string\l\
comparison: string\l\
pattern: string\l\
created_at: datetime\l\
updated_at: datetime\l\
published_at: datetime\l\
"
];
MetricFilterCriterion -> MetricFilter;
MetricType [
label = "MetricType|\
id: integer\l\
path: string\l\
created_at: datetime\l\
uuid: string\l\
stereotype: string\l\
"
];
PasswordToken [
label = "PasswordToken|\
id: integer\l\
account_id: integer\l\
address_id: integer\l\
code: string\l\
created_at: datetime\l\
updated_at: datetime\l\
"
];
PasswordToken -> Address;
PasswordToken -> Account;
Privilege [
label = "Privilege|\
id: integer\l\
name: string\l\
created_at: datetime\l\
"
];
Privilege -> Role [dir=both];
Role [
label = "Role|\
id: integer\l\
slug: string\l\
name: string\l\
client_id: integer\l\
uuid: string\l\
created_at: datetime\l\
updated_at: datetime\l\
"
];
Role -> Client;
Role -> Role;
Role -> Privilege [dir=both];
RoleAssignment [
label = "RoleAssignment|\
id: integer\l\
account_id: integer\l\
role_id: integer\l\
client_id: integer\l\
deactivated_at: datetime\l\
created_at: datetime\l\
"
];
RoleAssignment -> Client;
RoleAssignment -> Account;
RoleAssignment -> Role;
ServiceDescriptor [
label = "ServiceDescriptor|\
id: integer\l\
service_type: string\l\
href: string\l\
created_at: datetime\l\
"
];
UiLink [
label = "UiLink|\
id: string\l\
title: string\l\
target: string\l\
category: string\l\
created_at: datetime\l\
updated_at: datetime\l\
"
];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment