app/controllers/erd/erd_controller.rb in erd-0.6.4 vs app/controllers/erd/erd_controller.rb in erd-0.7.0
- old
+ new
@@ -4,66 +4,68 @@
require 'ruby-graphviz'
require 'erd/application_controller'
module Erd
class ErdController < ::Erd::ApplicationController
+ POSITIONS_JSON_FILE = Rails.root.join('tmp/erd_positions.json').freeze
+
def index
- plain = generate_plain
- positions = if (json = Rails.root.join('tmp/erd_positions.json')).exist?
- ActiveSupport::JSON.decode json.read
- else
- {}
- end
- @erd = render_plain plain, positions
+ @erd = render_plain generate_plain, saved_positions
+ end
+ def edit
+ @erd = render_plain generate_plain, saved_positions, true
@migrations = Erd::Migrator.status
end
def update
+ if params[:position_changes].present?
+ position_changes = ActiveSupport::JSON.decode(params[:position_changes])
+ positions = saved_positions
+ positions.merge! position_changes.transform_keys(&:tableize)
+ POSITIONS_JSON_FILE.open('w') {|f| f.write positions.to_json }
+ end
+
changes = params[:changes].present? ? ActiveSupport::JSON.decode(params[:changes]) : []
executed_migrations, failed_migrations = [], []
changes.each do |row|
begin
action, model, column, from, to = row['action'], row['model'], row['column'], row['from'], row['to']
- if action == 'move'
+
+ case action
+ when 'create_model'
+ columns = column.split(' ').compact
+ generated_migration_file = Erd::GenaratorRunner.execute_generate_model model, columns
+ when 'remove_model'
model = model.tableize
- json_file = Rails.root.join('tmp', 'erd_positions.json')
- positions = json_file.exist? ? ActiveSupport::JSON.decode(json_file.read) : {}
- positions[model] = to
- json_file.open('w') {|f| f.write positions.to_json}
+ generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "drop_#{model}"
+ gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n drop_table :#{model}\n end"
+ when 'rename_model'
+ _model, from, to = from.tableize, to.tableize, model.tableize
+ generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "rename_#{from}_to_#{to}"
+ gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n rename_table :#{from}, :#{to}\n end"
+ when 'add_column'
+ model = model.tableize
+ name_and_type = column.scan(/(.*)\((.*?)\)/).first
+ name, type = name_and_type[0], name_and_type[1]
+ generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "add_#{name}_to_#{model}", ["#{name}:#{type}"]
+ when 'rename_column'
+ model = model.tableize
+ generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "rename_#{model}_#{from}_to_#{to}"
+ gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n rename_column :#{model}, :#{from}, :#{to}\n end"
+ when 'alter_column'
+ model = model.tableize
+ generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "change_#{model}_#{column}_type_to_#{to}"
+ gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n change_column :#{model}, :#{column}, :#{to}\n end"
+ when 'move'
+ # do nothing
else
- case action
- when 'create_model'
- columns = column.split(' ').compact
- generated_migration_file = Erd::GenaratorRunner.execute_generate_model model, columns
- when 'remove_model'
- model = model.tableize
- generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "drop_#{model}"
- gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n drop_table :#{model}\n end"
- when 'rename_model'
- _model, from, to = from.tableize, to.tableize, model.tableize
- generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "rename_#{from}_to_#{to}"
- gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n rename_table :#{from}, :#{to}\n end"
- when 'add_column'
- model = model.tableize
- name_and_type = column.scan(/(.*)\((.*?)\)/).first
- name, type = name_and_type[0], name_and_type[1]
- generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "add_#{name}_to_#{model}", ["#{name}:#{type}"]
- when 'rename_column'
- model = model.tableize
- generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "rename_#{model}_#{from}_to_#{to}"
- gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n rename_column :#{model}, :#{from}, :#{to}\n end"
- when 'alter_column'
- model = model.tableize
- generated_migration_file = Erd::GenaratorRunner.execute_generate_migration "change_#{model}_#{column}_type_to_#{to}"
- gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n change_column :#{model}, :#{column}, :#{to}\n end"
- else
- raise "unexpected action: #{action}"
- end
- Erd::Migrator.run_migrations :up => generated_migration_file
- executed_migrations << generated_migration_file
+ raise "unexpected action: #{action}"
end
+
+ Erd::Migrator.run_migrations :up => generated_migration_file
+ executed_migrations << generated_migration_file
rescue ::Erd::MigrationError => e
failed_migrations << e.message
end
end
@@ -75,10 +77,14 @@
redirect_to erd.root_path, :flash => {:executed_migrations => params.slice(:up, :down)}
end
private
+ def saved_positions
+ POSITIONS_JSON_FILE.exist? ? ActiveSupport::JSON.decode(POSITIONS_JSON_FILE.read) : {}
+ end
+
def generate_plain
if Rails.respond_to?(:autoloaders) && Rails.autoloaders.try(:zeitwerk_enabled?)
Zeitwerk::Loader.eager_load_all
else
Rails.application.eager_load!
@@ -113,23 +119,24 @@
end
}
g.output('plain' => String)
end
- def render_plain(plain, positions)
+ def render_plain(plain, positions, edit_mode = false)
_scale, svg_width, svg_height = plain.scan(/\Agraph ([\d\.]+) ([\d\.]+) ([\d\.]+)$/).first
# node name x y width height label style shape color fillcolor
- max_model_x, max_model_y = 0, 0
models = plain.scan(/^node ([^ ]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([^ ]+) [^ ]+ [^ ]+ [^ ]+ [^ ]+\n/m).map {|model_name, x, y, width, height, label|
columns = label.gsub("\\\n", '').split('|')[1].split('\l').map {|name_and_type| name_and_type.scan(/(.*?)\((.*?)\)/).first }.map {|n, t| {:name => n, :type => t} }
custom_x, custom_y = positions[model_name.tableize].try(:split, ',')
- h = {:model => model_name, :x => (custom_x || (BigDecimal(x) * 72).round), :y => (custom_y || (BigDecimal(y) * 72).round), :width => (BigDecimal(width) * 72).round, :height => height, :columns => columns}
- max_model_x, max_model_y = [h[:x].to_i + h[:width].to_i, max_model_x, 1024].max, [h[:y].to_i + h[:height].to_i, max_model_y, 768].max
- h
+ {:model => model_name, :x => (custom_x || (BigDecimal(x) * 72).round), :y => (custom_y || (BigDecimal(y) * 72).round), :width => (BigDecimal(width) * 72).round, :height => (BigDecimal(height) * 72).round, :columns => columns}
}.compact
+ max_model_x = models.map {|m| m[:x].to_f + m[:width].to_f }.max
+ erd_width = [[(BigDecimal(svg_width) * 72).round, max_model_x].min + 150, 1024].max
+ max_model_y = models.map {|m| m[:y].to_f + m[:height].to_f }.max
+ erd_height = [[(BigDecimal(svg_height) * 72).round, max_model_y].min + 150, 768].max
# edge tail head n x1 y1 .. xn yn [label xl yl] style color
edges = plain.scan(/^edge ([^ ]+)+ ([^ ]+)/).map {|from, to| {:from => from, :to => to}}
- render_to_string 'erd/erd/erd', :layout => nil, :locals => {:width => [(BigDecimal(svg_width) * 72).round, max_model_x].max, :height => [(BigDecimal(svg_height) * 72).round, max_model_y].max, :models => models, :edges => edges}
+ render_to_string 'erd/erd/erd', :layout => nil, :locals => {:width => erd_width, :height => erd_height, :models => models, :edges => edges, :edit_mode => edit_mode}
end
def gsub_file(path, flag, *args, &block)
path = File.expand_path path, Rails.root