erd 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.rdoc +7 -5
- data/app/assets/javascripts/erd/erd.js.coffee +41 -3
- data/app/assets/stylesheets/erd/application.css +1 -0
- data/app/assets/stylesheets/erd/erd.css.scss +52 -0
- data/app/controllers/erd/erd_controller.rb +17 -4
- data/app/controllers/erd/models_controller.rb +9 -0
- data/app/views/erd/erd/index.html.erb +17 -1
- data/lib/erd/migrator.rb +18 -6
- data/lib/erd/railtie.rb +6 -4
- data/lib/erd/version.rb +1 -1
- data/vendor/assets/images/erd/animated-overlay.gif +0 -0
- data/vendor/assets/images/erd/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/vendor/assets/images/erd/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/vendor/assets/images/erd/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/vendor/assets/images/erd/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/vendor/assets/images/erd/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/vendor/assets/images/erd/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/vendor/assets/images/erd/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/vendor/assets/images/erd/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/vendor/assets/images/erd/ui-icons_222222_256x240.png +0 -0
- data/vendor/assets/images/erd/ui-icons_2e83ff_256x240.png +0 -0
- data/vendor/assets/images/erd/ui-icons_454545_256x240.png +0 -0
- data/vendor/assets/images/erd/ui-icons_888888_256x240.png +0 -0
- data/vendor/assets/images/erd/ui-icons_cd0a0a_256x240.png +0 -0
- data/vendor/assets/stylesheets/jquery-ui.css +1188 -0
- data/vendor/assets/stylesheets/jquery.ui.dialog.css +69 -0
- metadata +20 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f3eac74801a463df2f61072f1b5c507cc239a59
|
4
|
+
data.tar.gz: 93513fa3186082756f00f26ec6d64086b5f165cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d497649ac58ef2f0bfefcee033bf6a28846475f19b9e0c944a0abb38b59c153057c96d5f1a52a370f516f0dbe6f93c4a9ebc439f361b774e6ddf648d4b8a588
|
7
|
+
data.tar.gz: 8987e3253a555bc40448c3581b6463bb807421af495293e9b1950c033ecbb14da27c97373f54e37d5fc49ee8f5b3d7b94ed072549e888866cb3b5dd9f222b57e
|
data/README.rdoc
CHANGED
@@ -30,7 +30,7 @@ Browse at your http://localhost:3000/erd
|
|
30
30
|
|
31
31
|
* You can drag and arrange the positions of each model
|
32
32
|
|
33
|
-
* You can operate DB schema manipulations such as `add column`, `rename column`, `alter column`, and `drop table`
|
33
|
+
* You can operate DB schema manipulations such as `add column`, `rename column`, `alter column`, `create model (as well as table)`, and `drop table`
|
34
34
|
|
35
35
|
* Then, Erd generates migration files on the server
|
36
36
|
|
@@ -39,12 +39,8 @@ Browse at your http://localhost:3000/erd
|
|
39
39
|
|
40
40
|
== TODO
|
41
41
|
|
42
|
-
* Better UI
|
43
|
-
|
44
42
|
* Fix buggy JS
|
45
43
|
|
46
|
-
* create table (we need to generate AR model file at the same time)
|
47
|
-
|
48
44
|
* drop column (need to think of the UI)
|
49
45
|
|
50
46
|
* stop depending on rails-erd and Graphviz
|
@@ -59,6 +55,12 @@ Browse at your http://localhost:3000/erd
|
|
59
55
|
* Send me your pull requests!
|
60
56
|
|
61
57
|
|
58
|
+
=- Team
|
59
|
+
|
60
|
+
* {Akira Matsuda}[https://github.com/amatsuda]
|
61
|
+
* {Teppei Machida}[http://github.com/machida] (design)
|
62
|
+
|
63
|
+
|
62
64
|
== Copyright
|
63
65
|
|
64
66
|
Copyright (c) 2012 Akira Matsuda. See MIT-LICENSE for further details.
|
@@ -92,6 +92,8 @@ class ERD
|
|
92
92
|
$('div.model a.add_column').on 'click', @handle_add_column_click
|
93
93
|
$('div.model a.cancel').on 'click', @handle_cancel_click
|
94
94
|
$('div.model a.close').on 'click', @handle_remove_model_click
|
95
|
+
$('#new_model_add_column').on 'click', @handle_new_model_add_column_click
|
96
|
+
$('div.model a.cancel').on 'click', @handle_cancel_click
|
95
97
|
$('div#open_migration').on 'click', @handle_open_migration_click
|
96
98
|
$('div#close_migration').on 'click', @handle_close_migration_click
|
97
99
|
|
@@ -273,8 +275,8 @@ class ERD
|
|
273
275
|
|
274
276
|
return unless confirm('remove this table?')
|
275
277
|
|
276
|
-
model_name =
|
277
|
-
upsert_change 'remove_model', model_name, '', '', ''
|
278
|
+
model_name = m.data('model_name')
|
279
|
+
window.erd.upsert_change 'remove_model', model_name, '', '', ''
|
278
280
|
parent.hide()
|
279
281
|
|
280
282
|
$.each @edges, (i, edge) =>
|
@@ -282,6 +284,13 @@ class ERD
|
|
282
284
|
@paper.clear()
|
283
285
|
@connect_arrows(@edges)
|
284
286
|
|
287
|
+
handle_new_model_add_column_click: (ev) =>
|
288
|
+
ev.preventDefault()
|
289
|
+
target = $(ev.currentTarget)
|
290
|
+
|
291
|
+
target.parent().siblings('table').append('<tr><td><input type="text" /></td><td class="separator">:</td><td><input type="text" value="string" /></td></tr>').find('tr:last > td > input:first').focus()
|
292
|
+
|
293
|
+
|
285
294
|
handle_open_migration_click: (ev) =>
|
286
295
|
ev.preventDefault()
|
287
296
|
|
@@ -325,7 +334,10 @@ $ ->
|
|
325
334
|
$('#erd').css('height', window.innerHeight)
|
326
335
|
|
327
336
|
$("#open_migration").click ->
|
328
|
-
$('#close_migration').css('right', $('#migration').width() + ($(this).width() / 2) - 5)
|
337
|
+
$('#close_migration, #open_create_model_dialog').css('right', $('#migration').width() + ($(this).width() / 2) - 5)
|
338
|
+
|
339
|
+
$("#close_migration").click ->
|
340
|
+
$('#open_create_model_dialog').css('right', 15)
|
329
341
|
|
330
342
|
$('#open_up').click ->
|
331
343
|
$('#migration_status .up').addClass('open')
|
@@ -337,3 +349,29 @@ $ ->
|
|
337
349
|
|
338
350
|
$('#close_all').click ->
|
339
351
|
$('#migration_status tr').removeClass('open')
|
352
|
+
|
353
|
+
$('#create_model_form').dialog
|
354
|
+
autoOpen: false,
|
355
|
+
height: 450,
|
356
|
+
width: 450,
|
357
|
+
modal: true,
|
358
|
+
buttons:
|
359
|
+
'Create Model': ->
|
360
|
+
model = $('#new_model_name').val()
|
361
|
+
columns = ''
|
362
|
+
$('#create_model_table > tbody > tr').each (i, row) ->
|
363
|
+
[name, type] = $(row).find('input')
|
364
|
+
columns += "#{$(name).val()}:#{$(type).val()} "
|
365
|
+
window.erd.upsert_change 'create_model', model, columns, '', ''
|
366
|
+
$(this).find('table > tbody > tr').each (i, row) ->
|
367
|
+
row.remove() if i >= 1
|
368
|
+
$(this).find('input').val('')
|
369
|
+
$(this).find('input[name=new_model_column_type_1]').val('string')
|
370
|
+
|
371
|
+
$(this).dialog('close')
|
372
|
+
Cancel: ->
|
373
|
+
$(this).dialog('close')
|
374
|
+
|
375
|
+
$('#open_create_model_dialog').click (ev) ->
|
376
|
+
ev.preventDefault()
|
377
|
+
$('#create_model_form').dialog('open')
|
@@ -535,3 +535,55 @@ li {
|
|
535
535
|
#model_name_changes, #column_name_changes {
|
536
536
|
display: none;
|
537
537
|
}
|
538
|
+
|
539
|
+
#open_create_model_dialog {
|
540
|
+
position: fixed;
|
541
|
+
right: 15px;
|
542
|
+
top: 70px;
|
543
|
+
background: rgba(0, 0, 0, .6);
|
544
|
+
padding: 12px 20px;
|
545
|
+
color: $white;
|
546
|
+
text-decoration: none;
|
547
|
+
font-size: 13px;
|
548
|
+
&:hover {
|
549
|
+
background: rgba(0, 0, 0, .8)
|
550
|
+
}
|
551
|
+
}
|
552
|
+
|
553
|
+
#create_model_form {
|
554
|
+
font-size: 14px;
|
555
|
+
}
|
556
|
+
#create_model_table {
|
557
|
+
margin: 12px auto;
|
558
|
+
border-spacing: 0;
|
559
|
+
width: 100%;
|
560
|
+
tr {
|
561
|
+
&:nth-child(odd) {
|
562
|
+
td {
|
563
|
+
background: #f8f8f8;
|
564
|
+
}
|
565
|
+
}
|
566
|
+
&:nth-child(even) {
|
567
|
+
td {
|
568
|
+
background: #eee;
|
569
|
+
}
|
570
|
+
}
|
571
|
+
td {
|
572
|
+
padding: 6px 12px;
|
573
|
+
input {
|
574
|
+
width: 100%;
|
575
|
+
box-sizing: border-box;
|
576
|
+
}
|
577
|
+
&.separator {
|
578
|
+
padding: 6px 0;
|
579
|
+
}
|
580
|
+
}
|
581
|
+
}
|
582
|
+
}
|
583
|
+
#new_model_add_column {
|
584
|
+
margin: 10px auto 0;
|
585
|
+
display: block;
|
586
|
+
width: 160px;
|
587
|
+
padding: 2px 10px;
|
588
|
+
text-decoration: none;
|
589
|
+
}
|
@@ -24,36 +24,46 @@ module Erd
|
|
24
24
|
executed_migrations, failed_migrations = [], []
|
25
25
|
changes.each do |row|
|
26
26
|
begin
|
27
|
-
action, model, column, from, to = row['action'], row['model']
|
27
|
+
action, model, column, from, to = row['action'], row['model'], row['column'], row['from'], row['to']
|
28
28
|
case action
|
29
|
+
when 'create_model'
|
30
|
+
columns = column.split(' ').compact
|
31
|
+
generated_migration_file = Erd::Migrator.execute_generate_model model, columns
|
32
|
+
Erd::Migrator.run_migrations :up => generated_migration_file
|
33
|
+
executed_migrations << generated_migration_file
|
29
34
|
when 'remove_model'
|
35
|
+
model = model.tableize
|
30
36
|
generated_migration_file = Erd::Migrator.execute_generate_migration "drop_#{model}"
|
31
37
|
gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n drop_table :#{model}\n end"
|
32
38
|
Erd::Migrator.run_migrations :up => generated_migration_file
|
33
39
|
executed_migrations << generated_migration_file
|
34
40
|
when 'rename_model'
|
35
|
-
from, to = from.tableize, to.tableize
|
41
|
+
model, from, to = from.tableize, to.tableize, model.tableize
|
36
42
|
generated_migration_file = Erd::Migrator.execute_generate_migration "rename_#{from}_to_#{to}"
|
37
43
|
gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n rename_table :#{from}, :#{to}\n end"
|
38
44
|
Erd::Migrator.run_migrations :up => generated_migration_file
|
39
45
|
executed_migrations << generated_migration_file
|
40
46
|
when 'add_column'
|
47
|
+
model = model.tableize
|
41
48
|
name_and_type = column.scan(/(.*)\((.*?)\)/).first
|
42
49
|
name, type = name_and_type[0], name_and_type[1]
|
43
50
|
generated_migration_file = Erd::Migrator.execute_generate_migration "add_#{name}_to_#{model}", ["#{name}:#{type}"]
|
44
51
|
Erd::Migrator.run_migrations :up => generated_migration_file
|
45
52
|
executed_migrations << generated_migration_file
|
46
53
|
when 'rename_column'
|
54
|
+
model = model.tableize
|
47
55
|
generated_migration_file = Erd::Migrator.execute_generate_migration "rename_#{model}_#{from}_to_#{to}"
|
48
56
|
gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n rename_column :#{model}, :#{from}, :#{to}\n end"
|
49
57
|
Erd::Migrator.run_migrations :up => generated_migration_file
|
50
58
|
executed_migrations << generated_migration_file
|
51
59
|
when 'alter_column'
|
60
|
+
model = model.tableize
|
52
61
|
generated_migration_file = Erd::Migrator.execute_generate_migration "change_#{model}_#{column}_type_to_#{to}"
|
53
62
|
gsub_file generated_migration_file, /def (up|change).* end/m, "def change\n change_column :#{model}, :#{column}, :#{to}\n end"
|
54
63
|
Erd::Migrator.run_migrations :up => generated_migration_file
|
55
64
|
executed_migrations << generated_migration_file
|
56
65
|
when 'move'
|
66
|
+
model = model.tableize
|
57
67
|
json_file = Rails.root.join('tmp', 'erd_positions.json')
|
58
68
|
positions = json_file.exist? ? ActiveSupport::JSON.decode(json_file.read) : {}
|
59
69
|
positions[model] = to
|
@@ -78,6 +88,7 @@ module Erd
|
|
78
88
|
def render_plain(plain, positions)
|
79
89
|
_scale, svg_width, svg_height = plain.scan(/\Agraph ([0-9\.]+) ([0-9\.]+) ([0-9\.]+)$/).first
|
80
90
|
# node name x y width height label style shape color fillcolor
|
91
|
+
max_model_x, max_model_y = 0, 0
|
81
92
|
models = plain.scan(/^node ([^ ]+) ([0-9\.]+) ([0-9\.]+) ([0-9\.]+) ([0-9\.]+) <\{?(<((?!^\}?>).)*)^\}?> [^ ]+ [^ ]+ [^ ]+ [^ ]+\n/m).map {|node_name, x, y, width, height, label|
|
82
93
|
label_doc = Nokogiri::HTML::DocumentFragment.parse(label)
|
83
94
|
model_name = node_name.dup
|
@@ -89,11 +100,13 @@ module Erd
|
|
89
100
|
columns = cols_table.search('tr > td').map {|col| col_name, col_type = col.text.split(' '); {:name => col_name, :type => col_type}}
|
90
101
|
end
|
91
102
|
custom_x, custom_y = positions[model_name.tableize].try(:split, ',')
|
92
|
-
{: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}
|
103
|
+
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}
|
104
|
+
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
|
105
|
+
h
|
93
106
|
}.compact
|
94
107
|
# edge tail head n x1 y1 .. xn yn [label xl yl] style color
|
95
108
|
edges = plain.scan(/^edge ([^ ]+)+ ([^ ]+)/).map {|from, to| {:from => from.sub(/^m_/, ''), :to => to.sub(/^m_/, '')}}
|
96
|
-
render_to_string 'erd/erd/erd', :layout => nil, :locals => {:width => (BigDecimal(svg_width) * 72).round, :height => (BigDecimal(svg_height) * 72).round, :models => models, :edges => edges}
|
109
|
+
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}
|
97
110
|
end
|
98
111
|
|
99
112
|
def gsub_file(path, flag, *args, &block)
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Erd
|
2
|
+
class ModelsController < ::Erd::ApplicationController
|
3
|
+
# doesn't actually create anything. Just draw the given model
|
4
|
+
def create
|
5
|
+
model = {:model => params[:model_name], :x => 300, :y => 100, :width => 300, :height => 300, :columns => params[:columns]}
|
6
|
+
<%= render :partial => 'erd/erd/model', :object => model -%>
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -13,7 +13,7 @@
|
|
13
13
|
<h3><%= direction %></h3>
|
14
14
|
<ul>
|
15
15
|
<%- flash[:executed_migrations][direction].each do |m| -%>
|
16
|
-
<li><%= File.basename m %></li>
|
16
|
+
<li><%= File.basename m.to_s %></li>
|
17
17
|
<%- end -%>
|
18
18
|
</ul>
|
19
19
|
<%- end -%>
|
@@ -67,4 +67,20 @@
|
|
67
67
|
<%= submit_tag 'run migrations' %>
|
68
68
|
<% end %>
|
69
69
|
</div>
|
70
|
+
<a href="#" id='open_create_model_dialog'%>Create Model</a>
|
71
|
+
<div id="create_model_form">
|
72
|
+
<form>
|
73
|
+
Model Name: <input id="new_model_name" name="new_model_name" type="text" /><br>
|
74
|
+
<table id="create_model_table">
|
75
|
+
<tbody>
|
76
|
+
<tr>
|
77
|
+
<td><input name="new_model_column_name_1" type="text" /></td>
|
78
|
+
<td class="separator">:</td>
|
79
|
+
<td><input name="new_model_column_type_1" type="text" value="string" /></td>
|
80
|
+
</tr>
|
81
|
+
</tbody>
|
82
|
+
</table>
|
83
|
+
<div><a href="#" id="new_model_add_column" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"><span class="ui-button-text">Add More Column</span></a></div>
|
84
|
+
</form>
|
85
|
+
</div>
|
70
86
|
</div>
|
data/lib/erd/migrator.rb
CHANGED
@@ -40,15 +40,18 @@ module Erd
|
|
40
40
|
#TODO unload migraion classes
|
41
41
|
end
|
42
42
|
|
43
|
+
# runs `rails g model [name]`
|
44
|
+
# @return generated migration filename
|
45
|
+
def execute_generate_model(name, options = nil)
|
46
|
+
result = execute_generator 'model', name, options
|
47
|
+
result.flatten.grep(%r(/db/migrate/.*\.rb))
|
48
|
+
end
|
49
|
+
|
43
50
|
# runs `rails g migration [name]`
|
44
51
|
# @return generated migration filename
|
45
52
|
def execute_generate_migration(name, options = nil)
|
46
|
-
|
47
|
-
|
48
|
-
result = Rails::Generators.invoke 'migration', [name, options], :behavior => :invoke, :destination_root => Rails.root
|
49
|
-
raise ::Erd::MigrationError, "#{name}#{"(#{options})" if options}" unless result
|
50
|
-
result.last.last
|
51
|
-
end
|
53
|
+
result = execute_generator 'migration', name, options
|
54
|
+
result.last.last
|
52
55
|
end
|
53
56
|
|
54
57
|
private
|
@@ -60,6 +63,15 @@ module Erd
|
|
60
63
|
ensure
|
61
64
|
Object.const_set :ARGV, original_argv
|
62
65
|
end
|
66
|
+
|
67
|
+
def execute_generator(type, name, options = nil)
|
68
|
+
overwriting_argv([name, options]) do
|
69
|
+
Rails::Generators.configure! Rails.application.config.generators
|
70
|
+
result = Rails::Generators.invoke type, [name, options], :behavior => :invoke, :destination_root => Rails.root
|
71
|
+
raise ::Erd::MigrationError, "#{name}#{"(#{options})" if options}" unless result
|
72
|
+
result
|
73
|
+
end
|
74
|
+
end
|
63
75
|
end
|
64
76
|
end
|
65
77
|
end
|
data/lib/erd/railtie.rb
CHANGED
@@ -5,10 +5,12 @@ module Erd
|
|
5
5
|
autoload :Migrator, 'erd/migrator'
|
6
6
|
|
7
7
|
class Railtie < ::Rails::Railtie #:nodoc:
|
8
|
-
|
9
|
-
|
10
|
-
Rails.
|
11
|
-
|
8
|
+
initializer 'erd' do |app|
|
9
|
+
ActiveSupport.on_load(:after_initialize) do
|
10
|
+
if Rails.env.development?
|
11
|
+
Rails.application.routes.append do
|
12
|
+
mount Erd::Engine, :at => '/erd'
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
data/lib/erd/version.rb
CHANGED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|