forked from voormedia/rails-erd
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Rolf Timmermans
committed
Sep 19, 2010
1 parent
2bb409f
commit bb371f0
Showing
23 changed files
with
1,388 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
doc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
=== 0.1.0 | ||
|
||
* Released on September 20th, 2010. | ||
* First public release. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Copyright (c) 2010 Voormedia | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
= Rails ERD - Generate Entity-Relationship Diagrams for Rails applications | ||
|
||
Rails ERD is a Rails plugin that allows you to easily generate diagrams based | ||
on your ActiveRecord models. The diagrams give a great overview of how your | ||
models are related. Having a diagram that describes your models is perfect | ||
documentation for your application. | ||
|
||
Rails ERD was created specifically for Rails 3. It uses ActiveRecord reflection | ||
to figure out how your models are associated. | ||
|
||
== Getting started | ||
|
||
In its most simple form, Rails ERD is a plugin for Rails 3 that provides you | ||
with a Rake task to create an Entity-Relationship Diagram. It depends on the | ||
Graphviz visualisation library. You have to install Graphviz before using | ||
Rails ERD. In order to create PDF files (the default), you should install | ||
or compile Graphviz with Pango/Cairo. | ||
|
||
For example, to install Graphviz with MacPorts: | ||
|
||
% sudo port install graphviz | ||
|
||
Or with Homebrew: | ||
|
||
% brew install cairo pango graphviz | ||
|
||
Next, install Rails ERD. Open your +Gemfile+, and add the following: | ||
|
||
group :development do | ||
gem 'rails-erd' | ||
end | ||
|
||
Tell Bundler to install Rails ERD: | ||
|
||
% bundle install | ||
|
||
You now have access to Rails ERD through Rake. Generate a new | ||
Entity-Relationship Diagram for your Rails application: | ||
|
||
% rake erd | ||
|
||
All done! You will now have a file named +ERD.pdf+ in your application root. | ||
|
||
== Advanced use | ||
|
||
Rails ERD has several options that you can use to customise its behaviour. | ||
All options can be provided on the command line. For example: | ||
|
||
% rake erd exclude_timestamps=false | ||
|
||
For an overview of all available options, see the documentation of RailsERD: | ||
http://rails-erd.rubyforge.org/doc/ | ||
|
||
== License | ||
|
||
Rails ERD is released under the MIT license. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# encoding: utf-8 | ||
require "jeweler" | ||
require "rake/testtask" | ||
|
||
Jeweler::Tasks.new do |spec| | ||
spec.name = "rails-erd" | ||
spec.rubyforge_project = "rails-erd" | ||
spec.summary = "Entity-relationship diagram for your Rails models." | ||
spec.description = "Automatically generate an entity-relationship diagram (ERD) for the models in your Rails application." | ||
|
||
spec.authors = ["Rolf Timmermans"] | ||
spec.email = "r.timmermans@voormedia.com" | ||
spec.homepage = "http://rails-erd.rubyforge.org/" | ||
|
||
spec.add_runtime_dependency "activesupport", "~> 3.0.0" | ||
spec.add_runtime_dependency "ruby-graphviz", "~> 0.9.17" | ||
end | ||
|
||
Jeweler::GemcutterTasks.new | ||
|
||
Jeweler::RubyforgeTasks.new do |rubyforge| | ||
rubyforge.doc_task = "rdoc" | ||
end | ||
|
||
Rake::TestTask.new do |test| | ||
test.pattern = "test/unit/**/*_test.rb" | ||
end | ||
|
||
begin | ||
require "hanna/rdoctask" | ||
Rake::RDocTask.new do |rdoc| | ||
rdoc.rdoc_files = Dir["[A-Z][A-Z]*"] + Dir["lib/**/*.rb"] | ||
rdoc.title = "Rails ERD – Entity-Relationship Diagrams for Rails" | ||
rdoc.rdoc_dir = "doc" | ||
end | ||
rescue => e | ||
puts e.message | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
require "rails_erd" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
require "active_support/ordered_options" | ||
require "rails_erd/railtie" if defined? Rails | ||
|
||
# Rails ERD provides several options that allow you to customise the | ||
# generation of the diagram and the domain model itself. Currently, the | ||
# following options are supported: | ||
# | ||
# type:: The file type of the generated diagram. Defaults to +:pdf+, which | ||
# is the recommended format. Other formats may render significantly | ||
# worse than a PDF file. | ||
# orientation:: The direction of the hierarchy of entities. Either +:horizontal+ | ||
# or +:vertical+. Defaults to +:horizontal+. | ||
# suppress_warnings:: When set to +true+, no warnings are printed to the | ||
# command line while processing the domain model. Defaults | ||
# to +false+. | ||
# exclude_timestamps:: Excludes timestamp columns (<tt>created_at/on</tt> and | ||
# <tt>updated_at/on</tt>) from attribute lists. Defaults | ||
# to +true+. | ||
# exclude_primary_keys:: Excludes primary key columns from attribute lists. | ||
# Defaults to +true+. | ||
# exclude_foreign_keys:: Excludes foreign key columns from attribute lists. | ||
# Defaults to +true+. | ||
module RailsERD | ||
class << self | ||
# Access to default options. Any instance of RailsERD::Domain and | ||
# RailsERD::Diagram will use these options unless overridden. | ||
attr_accessor :options | ||
end | ||
|
||
self.options = ActiveSupport::OrderedOptions[ | ||
:type, :pdf, | ||
:orientation, :horizontal, | ||
:exclude_timestamps, true, | ||
:exclude_primary_keys, true, | ||
:exclude_foreign_keys, true, | ||
:suppress_warnings, false | ||
] | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# -*- encoding: utf-8 | ||
module RailsERD | ||
class Attribute | ||
TIMESTAMP_NAMES = %w{created_at created_on updated_at updated_on} #:nodoc: | ||
|
||
class << self | ||
def from_model(domain, model) #:nodoc: | ||
model.arel_table.columns.collect { |column| Attribute.new(domain, model, column) }.sort | ||
end | ||
end | ||
|
||
attr_reader :column #:nodoc: | ||
|
||
def initialize(domain, model, column) | ||
@domain, @model, @column = domain, model, column | ||
end | ||
|
||
def name | ||
column.name | ||
end | ||
|
||
def type | ||
column.type | ||
end | ||
|
||
def mandatory? | ||
!column.null or @model.validators_on(name).map(&:kind).include?(:presence) | ||
end | ||
|
||
def primary_key? | ||
@model.arel_table.primary_key == name | ||
end | ||
|
||
def foreign_key? | ||
@domain.relationships_for(@model).map(&:associations).flatten.map(&:primary_key_name).include?(name) | ||
end | ||
|
||
def timestamp? | ||
TIMESTAMP_NAMES.include? name | ||
end | ||
|
||
def <=>(other) #:nodoc: | ||
name <=> other.name | ||
end | ||
|
||
def inspect #:nodoc: | ||
"#<#{self.class.name}:0x%.14x @column=#{name.inspect} @type=#{type.inspect}>" % (object_id << 1) | ||
end | ||
|
||
def to_s #:nodoc: | ||
name | ||
end | ||
|
||
def type_description | ||
case type | ||
when :integer then "int" | ||
when :float then "float" | ||
when :decimal then "dec" | ||
when :datetime then "datetime" | ||
when :date then "date" | ||
when :timestamp then "timest" | ||
when :time then "time" | ||
when :text then "txt" | ||
when :string then "str" | ||
when :binary then "blob" | ||
when :boolean then "bool" | ||
else type.to_s | ||
end.tap do |desc| | ||
desc << " (#{column.limit})" if column.limit != @model.connection.native_database_types[type][:limit] | ||
desc << " ∗" if mandatory? # Add a hair space + low asterisk (Unicode characters). | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
require "rails_erd/domain" | ||
require "graphviz" | ||
|
||
module RailsERD | ||
class Diagram | ||
NODE_LABEL_TEMPLATE = File.read(File.expand_path("templates/node.erb", File.dirname(__FILE__))) #:nodoc: | ||
NODE_WIDTH = 130 #:nodoc: | ||
|
||
class << self | ||
def generate(options = {}) | ||
new(Domain.generate(options), options).output | ||
end | ||
end | ||
|
||
attr_reader :options #:nodoc: | ||
|
||
def initialize(domain, options = {}) | ||
@domain, @options = domain, RailsERD.options.merge(options) | ||
end | ||
|
||
def graph | ||
@graph ||= GraphViz.new(@domain.name, :type => :digraph) do |graph| | ||
graph[:rankdir] = horizontal? ? :LR : :TB | ||
graph[:ranksep] = 0.5 | ||
graph[:nodesep] = 0.35 | ||
graph[:margin] = "0.4,0.4" | ||
graph[:concentrate] = true | ||
graph[:label] = "#{@domain.name} domain model\\n\\n" | ||
graph[:labelloc] = :t | ||
graph[:fontsize] = 13 | ||
graph[:fontname] = "Arial Bold" | ||
graph[:remincross] = true | ||
graph[:outputorder] = :edgesfirst | ||
|
||
graph.node[:shape] = "Mrecord" | ||
graph.node[:fontsize] = 10 | ||
graph.node[:fontname] = "Arial" | ||
graph.node[:margin] = "0.07,0.05" | ||
|
||
graph.edge[:fontname] = "Arial" | ||
graph.edge[:fontsize] = 8 | ||
graph.edge[:dir] = :both | ||
graph.edge[:arrowsize] = 0.8 | ||
|
||
nodes = {} | ||
|
||
@domain.entities.select(&:connected?).each do |entity| | ||
attributes = entity.attributes.reject { |attribute| | ||
options.exclude_primary_keys && attribute.primary_key? or | ||
options.exclude_foreign_keys && attribute.foreign_key? or | ||
options.exclude_timestamps && attribute.timestamp? | ||
} | ||
|
||
nodes[entity] = graph.add_node entity.name, :html => ERB.new(NODE_LABEL_TEMPLATE, nil, "<>").result(binding) | ||
end | ||
|
||
@domain.relationships.each do |relationship| | ||
options = {} | ||
options[:arrowhead] = relationship.cardinality.one_to_one? ? :dot : :normal | ||
options[:arrowtail] = relationship.cardinality.many_to_many? ? :normal : :dot | ||
options[:weight] = relationship.strength | ||
options.merge! :style => :dashed, :constraint => false if relationship.indirect? | ||
|
||
graph.add_edge nodes[relationship.source], nodes[relationship.destination], options | ||
end | ||
end | ||
end | ||
|
||
def output | ||
graph.output(options.type.to_sym => file_name) | ||
self | ||
end | ||
|
||
def file_name | ||
"ERD.#{options.type}" | ||
end | ||
|
||
private | ||
|
||
def horizontal? | ||
options.orientation == :horizontal | ||
end | ||
|
||
def vertical? | ||
!horizontal? | ||
end | ||
end | ||
end |
Oops, something went wrong.