neo4j-meta_model 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +37 -0
- data/app/assets/javascripts/admin/models.js.coffee +25 -0
- data/app/assets/javascripts/meta_model.js.coffee +217 -0
- data/app/assets/javascripts/router.js.coffee +5 -0
- data/app/assets/javascripts/store.js.coffee +12 -0
- data/app/assets/javascripts/templates/application.emblem +3 -0
- data/app/assets/javascripts/templates/components/model-list-item.emblem +6 -0
- data/app/assets/javascripts/templates/components/model-list.emblem +4 -0
- data/app/assets/javascripts/templates/has_associations/index.emblem +25 -0
- data/app/assets/javascripts/templates/has_associations/new.emblem +50 -0
- data/app/assets/javascripts/templates/index.emblem +6 -0
- data/app/assets/javascripts/templates/models/edit.emblem +40 -0
- data/app/assets/javascripts/templates/models/hierarchy.emblem +8 -0
- data/app/assets/stylesheets/meta_model.css.scss +113 -0
- data/app/controllers/meta_model/application_controller.rb +12 -0
- data/app/controllers/meta_model/meta/has_associations_controller.rb +44 -0
- data/app/controllers/meta_model/meta/models_controller.rb +80 -0
- data/app/controllers/meta_model/meta/properties_controller.rb +36 -0
- data/app/controllers/meta_model/meta_controller.rb +7 -0
- data/app/controllers/meta_model/models_controller.rb +69 -0
- data/app/helpers/meta_model/application_helper.rb +10 -0
- data/app/helpers/meta_model/model_helper.rb +10 -0
- data/app/models/concerns/meta_model/model_base.rb +43 -0
- data/app/models/meta_model/has_association.rb +46 -0
- data/app/models/meta_model/meta_model_base.rb +7 -0
- data/app/models/meta_model/model.rb +51 -0
- data/app/models/meta_model/property.rb +11 -0
- data/app/serializers/meta_model/has_association_serializer.rb +13 -0
- data/app/serializers/meta_model/model_serializer.rb +11 -0
- data/app/serializers/meta_model/property_serializer.rb +6 -0
- data/app/views/layouts/meta_model.html.slim +28 -0
- data/app/views/meta_model/meta/associations/index.html.slim +12 -0
- data/app/views/meta_model/meta/index.html.slim +2 -0
- data/app/views/meta_model/meta/models/edit.html.slim +39 -0
- data/app/views/meta_model/models/_form.html.slim +72 -0
- data/app/views/meta_model/models/_has_many_association.html.slim +4 -0
- data/app/views/meta_model/models/_record_details.html.slim +13 -0
- data/app/views/meta_model/models/edit.html.slim +6 -0
- data/app/views/meta_model/models/index.html.slim +14 -0
- data/app/views/meta_model/models/meta_index.html.slim +6 -0
- data/app/views/meta_model/models/new.html.slim +7 -0
- data/app/views/meta_model/models/show.html.slim +18 -0
- data/config/initializers/active_model_serializer.rb +6 -0
- data/config/routes.rb +19 -0
- data/lib/ext/hash.rb +7 -0
- data/lib/meta_model/engine.rb +23 -0
- data/lib/meta_model/version.rb +3 -0
- data/lib/meta_model.rb +4 -0
- data/lib/meta_models.rb +70 -0
- data/lib/tasks/meta_model_tasks.rake +4 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +14 -0
- data/test/dummy/app/assets/stylesheets/meta_model.css.scss +55 -0
- data/test/dummy/app/controllers/meta_model/application_controller.rb +8 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config/application.rb +29 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +79 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +21 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/meta_model_test.rb +7 -0
- data/test/test_helper.rb +19 -0
- data/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.eot +0 -0
- data/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.svg +288 -0
- data/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf +0 -0
- data/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.woff +0 -0
- data/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.woff2 +0 -0
- data/vendor/assets/javascripts/backbone.js +1608 -0
- data/vendor/assets/javascripts/bootstrap/affix.js +162 -0
- data/vendor/assets/javascripts/bootstrap/alert.js +94 -0
- data/vendor/assets/javascripts/bootstrap/button.js +116 -0
- data/vendor/assets/javascripts/bootstrap/carousel.js +240 -0
- data/vendor/assets/javascripts/bootstrap/collapse.js +211 -0
- data/vendor/assets/javascripts/bootstrap/dropdown.js +161 -0
- data/vendor/assets/javascripts/bootstrap/modal.js +324 -0
- data/vendor/assets/javascripts/bootstrap/popover.js +119 -0
- data/vendor/assets/javascripts/bootstrap/scrollspy.js +175 -0
- data/vendor/assets/javascripts/bootstrap/tab.js +153 -0
- data/vendor/assets/javascripts/bootstrap/tooltip.js +478 -0
- data/vendor/assets/javascripts/bootstrap/transition.js +59 -0
- data/vendor/assets/javascripts/bootstrap-sprockets.js +12 -0
- data/vendor/assets/javascripts/bootstrap.js +2304 -0
- data/vendor/assets/javascripts/lodash.js +6785 -0
- data/vendor/assets/javascripts/rivets-backbone.js +97 -0
- data/vendor/assets/javascripts/rivets.js +1273 -0
- data/vendor/assets/javascripts/sightglass.js +203 -0
- data/vendor/assets/stylesheets/_bootstrap-compass.scss +7 -0
- data/vendor/assets/stylesheets/_bootstrap-mincer.scss +17 -0
- data/vendor/assets/stylesheets/_bootstrap-sprockets.scss +7 -0
- data/vendor/assets/stylesheets/_bootstrap.scss +50 -0
- data/vendor/assets/stylesheets/bootstrap/_alerts.scss +68 -0
- data/vendor/assets/stylesheets/bootstrap/_badges.scss +63 -0
- data/vendor/assets/stylesheets/bootstrap/_breadcrumbs.scss +26 -0
- data/vendor/assets/stylesheets/bootstrap/_button-groups.scss +243 -0
- data/vendor/assets/stylesheets/bootstrap/_buttons.scss +160 -0
- data/vendor/assets/stylesheets/bootstrap/_carousel.scss +267 -0
- data/vendor/assets/stylesheets/bootstrap/_close.scss +35 -0
- data/vendor/assets/stylesheets/bootstrap/_code.scss +69 -0
- data/vendor/assets/stylesheets/bootstrap/_component-animations.scss +38 -0
- data/vendor/assets/stylesheets/bootstrap/_dropdowns.scss +213 -0
- data/vendor/assets/stylesheets/bootstrap/_forms.scss +548 -0
- data/vendor/assets/stylesheets/bootstrap/_glyphicons.scss +236 -0
- data/vendor/assets/stylesheets/bootstrap/_grid.scss +84 -0
- data/vendor/assets/stylesheets/bootstrap/_input-groups.scss +166 -0
- data/vendor/assets/stylesheets/bootstrap/_jumbotron.scss +49 -0
- data/vendor/assets/stylesheets/bootstrap/_labels.scss +66 -0
- data/vendor/assets/stylesheets/bootstrap/_list-group.scss +124 -0
- data/vendor/assets/stylesheets/bootstrap/_media.scss +47 -0
- data/vendor/assets/stylesheets/bootstrap/_mixins.scss +39 -0
- data/vendor/assets/stylesheets/bootstrap/_modals.scss +148 -0
- data/vendor/assets/stylesheets/bootstrap/_navbar.scss +662 -0
- data/vendor/assets/stylesheets/bootstrap/_navs.scss +244 -0
- data/vendor/assets/stylesheets/bootstrap/_normalize.scss +427 -0
- data/vendor/assets/stylesheets/bootstrap/_pager.scss +54 -0
- data/vendor/assets/stylesheets/bootstrap/_pagination.scss +88 -0
- data/vendor/assets/stylesheets/bootstrap/_panels.scss +261 -0
- data/vendor/assets/stylesheets/bootstrap/_popovers.scss +135 -0
- data/vendor/assets/stylesheets/bootstrap/_print.scss +107 -0
- data/vendor/assets/stylesheets/bootstrap/_progress-bars.scss +87 -0
- data/vendor/assets/stylesheets/bootstrap/_responsive-embed.scss +35 -0
- data/vendor/assets/stylesheets/bootstrap/_responsive-utilities.scss +174 -0
- data/vendor/assets/stylesheets/bootstrap/_scaffolding.scss +150 -0
- data/vendor/assets/stylesheets/bootstrap/_tables.scss +234 -0
- data/vendor/assets/stylesheets/bootstrap/_theme.scss +272 -0
- data/vendor/assets/stylesheets/bootstrap/_thumbnails.scss +38 -0
- data/vendor/assets/stylesheets/bootstrap/_tooltip.scss +103 -0
- data/vendor/assets/stylesheets/bootstrap/_type.scss +298 -0
- data/vendor/assets/stylesheets/bootstrap/_utilities.scss +56 -0
- data/vendor/assets/stylesheets/bootstrap/_variables.scss +864 -0
- data/vendor/assets/stylesheets/bootstrap/_wells.scss +29 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_alerts.scss +14 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_background-variant.scss +11 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_border-radius.scss +18 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_buttons.scss +52 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_center-block.scss +7 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_clearfix.scss +22 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_forms.scss +88 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_gradients.scss +58 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +81 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_grid.scss +122 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_hide-text.scss +21 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_image.scss +33 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_labels.scss +12 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_list-group.scss +31 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +10 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_nav-vertical-align.scss +9 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_opacity.scss +8 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_pagination.scss +23 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_panels.scss +24 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_progress-bar.scss +10 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_reset-filter.scss +8 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_resize.scss +6 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_responsive-visibility.scss +21 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_size.scss +10 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_tab-focus.scss +9 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_table-row.scss +28 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +11 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_text-overflow.scss +8 -0
- data/vendor/assets/stylesheets/bootstrap/mixins/_vendor-prefixes.scss +222 -0
- metadata +365 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 07e1c07aba0b7ca1af37de940a7360a857b2a694
|
4
|
+
data.tar.gz: 653df4a5130509b8dae8d9c92a1b3a24f85ba7e0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 25a6f101b7448a6978dddc5bbaa8c1f7120b8b1c457827d2fae70ae0e8357ded94d4173ab0ff0eace99874fc9eed83bfafe1f7c7b342d3c8fbc2f95d8d4c5461
|
7
|
+
data.tar.gz: ab92afb8847b05562a909efe8f69211081317ef0a1dca17de257de878a291ad9c477a78ff1f9194d4c6e88f435fdb2ec90c6fa0c6b7afdfc9932283674e4c99a
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2015 Brian Underwood
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'MetaModel'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
load 'rails/tasks/statistics.rake'
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
Bundler::GemHelper.install_tasks
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
30
|
+
t.libs << 'lib'
|
31
|
+
t.libs << 'test'
|
32
|
+
t.pattern = 'test/**/*_test.rb'
|
33
|
+
t.verbose = false
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
task default: :test
|
@@ -0,0 +1,25 @@
|
|
1
|
+
ready = ->
|
2
|
+
$('.propertes .add').click ->
|
3
|
+
clone = $('.property').last().clone()
|
4
|
+
|
5
|
+
$('.properties').append(clone)
|
6
|
+
|
7
|
+
clone.find('input').val('')
|
8
|
+
|
9
|
+
|
10
|
+
$('.associations .add').click ->
|
11
|
+
clone = $('.associations .association').last().clone()
|
12
|
+
|
13
|
+
$('.associations').append(clone)
|
14
|
+
|
15
|
+
clone.find('input').val('')
|
16
|
+
|
17
|
+
|
18
|
+
$('.property .close').click ->
|
19
|
+
$(this).parent('.property').remove()
|
20
|
+
|
21
|
+
$('.association .close').click ->
|
22
|
+
$(this).parent('.association').remove()
|
23
|
+
|
24
|
+
$(document).ready ready
|
25
|
+
$(document).on 'page:load', ready
|
@@ -0,0 +1,217 @@
|
|
1
|
+
#= require lodash
|
2
|
+
#= require jquery
|
3
|
+
#= require jquery_ujs
|
4
|
+
#= require handlebars
|
5
|
+
#= require ember
|
6
|
+
#= require ember-data
|
7
|
+
|
8
|
+
|
9
|
+
#= require sightglass
|
10
|
+
#= require rivets
|
11
|
+
#= require backbone
|
12
|
+
#= require rivets-backbone
|
13
|
+
|
14
|
+
|
15
|
+
#= require ./store
|
16
|
+
#= require_tree ./models
|
17
|
+
#= require_tree ./controllers
|
18
|
+
#= require_tree ./views
|
19
|
+
#= require_tree ./helpers
|
20
|
+
#= require_tree ./components
|
21
|
+
#= require_tree ./templates
|
22
|
+
#= require_tree ./routes
|
23
|
+
#= require ./router
|
24
|
+
#= require_self
|
25
|
+
|
26
|
+
mm_path = (path) ->
|
27
|
+
base_path = meta_model_root_path
|
28
|
+
|
29
|
+
base_path = base_path[0..-2] if base_path[-1..-1] is '/'
|
30
|
+
|
31
|
+
p = path
|
32
|
+
p = p[1..-1] if p[0] is '/'
|
33
|
+
|
34
|
+
base_path + '/' + p
|
35
|
+
|
36
|
+
|
37
|
+
# for more details see: http://emberjs.com/guides/application/
|
38
|
+
#window.MetaModel = Ember.Application.create(rootElement: '#ember-application')
|
39
|
+
|
40
|
+
MetaModel.ApplicationController = Ember.Controller.extend()
|
41
|
+
|
42
|
+
MetaModel.Model = DS.Model.extend()
|
43
|
+
|
44
|
+
console.log {path: mm_path('meta')[1..-1]}
|
45
|
+
MetaModel.MetaModelAdapter = DS.RESTAdapter.extend
|
46
|
+
namespace: mm_path('meta')[1..-1]
|
47
|
+
|
48
|
+
MetaModel.ModelAdapter = MetaModel.MetaModelAdapter.extend()
|
49
|
+
MetaModel.PropertyAdapter = MetaModel.MetaModelAdapter.extend()
|
50
|
+
|
51
|
+
MetaModel.HasAssociationAdapter = MetaModel.MetaModelAdapter.extend
|
52
|
+
buildURL: (type, id, record) ->
|
53
|
+
result = "/meta/has_associations"
|
54
|
+
result += "/#{id}" if id
|
55
|
+
mm_path result
|
56
|
+
|
57
|
+
|
58
|
+
MetaModel.Router.map ->
|
59
|
+
@route 'index', path: "/"
|
60
|
+
|
61
|
+
@resource 'models', path: '/models', ->
|
62
|
+
@route 'hierarchy', path: "/"
|
63
|
+
@route 'edit', path: "/:class_name/edit"
|
64
|
+
|
65
|
+
@resource 'has_associations', ->
|
66
|
+
@route 'index', path: '/'
|
67
|
+
@route 'new', path: '/new'
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
MetaModel.ApplicationAdapter = DS.ActiveModelAdapter.extend()
|
72
|
+
|
73
|
+
MetaModel.ApplicationSerializer = DS.ActiveModelSerializer.extend()
|
74
|
+
|
75
|
+
# Components
|
76
|
+
|
77
|
+
MetaModel.FocusInputComponent = Ember.TextField.extend
|
78
|
+
becomeFocused: (->
|
79
|
+
@$().focus()
|
80
|
+
).on('didInsertElement')
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
MetaModel.ModelListItemComponent = Ember.Component.extend
|
85
|
+
action: 'meta_model_clicked'
|
86
|
+
actions:
|
87
|
+
clicked: ->
|
88
|
+
@sendAction 'action', @get('model')
|
89
|
+
goto_metamodel: (model) ->
|
90
|
+
@sendAction 'action', model
|
91
|
+
|
92
|
+
MetaModel.ModelListComponent = Ember.Component.extend
|
93
|
+
action: 'goto_metamodel'
|
94
|
+
actions:
|
95
|
+
meta_model_clicked: (model) ->
|
96
|
+
@sendAction 'action', model
|
97
|
+
|
98
|
+
|
99
|
+
# Models
|
100
|
+
|
101
|
+
MetaModel.Property = DS.Model.extend
|
102
|
+
name: DS.attr 'string'
|
103
|
+
type: DS.attr 'string'
|
104
|
+
model: DS.belongsTo 'Model', inverse: 'properties'
|
105
|
+
|
106
|
+
MetaModel.Model = DS.Model.extend
|
107
|
+
class_name: DS.attr 'string'
|
108
|
+
superclass_model: DS.belongsTo 'Model'
|
109
|
+
#superclass_model: DS.attr 'string'
|
110
|
+
properties: DS.hasMany 'Property'
|
111
|
+
source_has_associations: DS.hasMany 'HasAssociation', inverse: 'to_model'
|
112
|
+
destination_has_associations: DS.hasMany 'HasAssociation', inverse: 'from_model'
|
113
|
+
|
114
|
+
MetaModel.HasAssociation = DS.Model.extend
|
115
|
+
join_type: DS.attr 'string'
|
116
|
+
name: DS.attr 'string'
|
117
|
+
opposite_name: DS.attr 'string'
|
118
|
+
relationship_type: DS.attr 'string'
|
119
|
+
from_model: DS.belongsTo 'Model', async: true
|
120
|
+
to_model: DS.belongsTo 'Model', async: true
|
121
|
+
|
122
|
+
source_join_type: (->
|
123
|
+
@get('join_type')?.split('_to_')[0]
|
124
|
+
).property('join_type')
|
125
|
+
|
126
|
+
destination_join_type: (->
|
127
|
+
@get('join_type')?.split('_to_')[1]
|
128
|
+
).property('join_type')
|
129
|
+
|
130
|
+
source_is_defined: (->
|
131
|
+
@get('source_join_type') and @get('from_model')
|
132
|
+
).property('source_join_type', 'from_model')
|
133
|
+
|
134
|
+
destination_is_defined: (->
|
135
|
+
@get('destination_join_type') and @get('to_model')
|
136
|
+
).property('destination_join_type', 'to_model')
|
137
|
+
|
138
|
+
models_are_defined: (->
|
139
|
+
@get('from_model') and @get('to_model')
|
140
|
+
).property('from_model', 'to_model')
|
141
|
+
|
142
|
+
|
143
|
+
standardize_relationship_type: (->
|
144
|
+
@set 'relationship_type', @get('relationship_type').toLowerCase().replace(/[^a-z0-9]+/g, '_')
|
145
|
+
).observes('relationship_type')
|
146
|
+
|
147
|
+
|
148
|
+
# Routes / Controllers
|
149
|
+
|
150
|
+
|
151
|
+
MetaModel.ModelsHierarchyRoute = Ember.Route.extend
|
152
|
+
model: ->
|
153
|
+
Ember.$.getJSON(mm_path '/meta/models/hierarchy.json').then (data) ->
|
154
|
+
data.models
|
155
|
+
actions:
|
156
|
+
goto_metamodel: (model) ->
|
157
|
+
@transitionTo 'models.edit', model.class_name
|
158
|
+
|
159
|
+
|
160
|
+
MetaModel.ModelsHierarchyController = Ember.Controller.extend
|
161
|
+
new_model_name: ''
|
162
|
+
|
163
|
+
actions:
|
164
|
+
add: (class_name) ->
|
165
|
+
@store.createRecord('model', class_name: @new_model_name).save().then (record) =>
|
166
|
+
@transitionToRoute 'models.edit', queryParams: class_name: record.class_name
|
167
|
+
|
168
|
+
|
169
|
+
MetaModel.ModelsEditRoute = Ember.Route.extend
|
170
|
+
model: (params) ->
|
171
|
+
Ember.RSVP.hash
|
172
|
+
model: @store.find 'model', params.class_name
|
173
|
+
models: @store.find 'model'
|
174
|
+
property_types: ['String', 'DateTime']
|
175
|
+
|
176
|
+
actions:
|
177
|
+
add_property: (model) ->
|
178
|
+
property = model.get('properties').createRecord name: '', type: 'String', model_id: model.id
|
179
|
+
property.save()
|
180
|
+
|
181
|
+
delete_property: (property) ->
|
182
|
+
property.destroyRecord()
|
183
|
+
|
184
|
+
save: (model) ->
|
185
|
+
model.save() #if model.get 'isDirty'
|
186
|
+
model.get('properties').forEach (property) ->
|
187
|
+
property.save() if property.get 'isDirty'
|
188
|
+
|
189
|
+
delete: (model) ->
|
190
|
+
model.destroyRecord().then =>
|
191
|
+
@transitionTo 'models.hierarchy'
|
192
|
+
|
193
|
+
MetaModel.HasAssociationsIndexRoute = Ember.Route.extend
|
194
|
+
model: (params) ->
|
195
|
+
@store.find 'has_association'
|
196
|
+
|
197
|
+
actions:
|
198
|
+
delete: (has_association) ->
|
199
|
+
has_association.destroyRecord()
|
200
|
+
|
201
|
+
|
202
|
+
|
203
|
+
MetaModel.HasAssociationsNewRoute = Ember.Route.extend
|
204
|
+
model: (params) ->
|
205
|
+
Ember.RSVP.hash
|
206
|
+
has_association: @store.createRecord 'has_association'
|
207
|
+
models: @store.find 'model'
|
208
|
+
join_types: ['one_to_many', 'many_to_one', 'many_to_many']
|
209
|
+
|
210
|
+
actions:
|
211
|
+
create: (has_association) ->
|
212
|
+
console.log 'create!'
|
213
|
+
has_association.save().then (record) =>
|
214
|
+
@transitionToRoute 'has_associations.index'
|
215
|
+
|
216
|
+
|
217
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# http://emberjs.com/guides/models/#toc_store
|
2
|
+
# http://emberjs.com/guides/models/pushing-records-into-the-store/
|
3
|
+
|
4
|
+
#MetaModel.ApplicationStore = DS.Store.extend({
|
5
|
+
#
|
6
|
+
#})
|
7
|
+
|
8
|
+
# Override the default adapter with the `DS.ActiveModelAdapter` which
|
9
|
+
# is built to work nicely with the ActiveModel::Serializers gem.
|
10
|
+
#MetaModel.ApplicationAdapter = DS.ActiveModelAdapter.extend({
|
11
|
+
#
|
12
|
+
#})
|
@@ -0,0 +1,25 @@
|
|
1
|
+
link-to "has_associations.new" | New Association
|
2
|
+
|
3
|
+
table#has-associations-table.table.table-striped.table-bordered
|
4
|
+
each has_association in model
|
5
|
+
tr
|
6
|
+
td
|
7
|
+
= has_association.from_model.class_name
|
8
|
+
.relationship
|
9
|
+
span.source-join-type
|
10
|
+
= has_association.source_join_type
|
11
|
+
span.source-association-name
|
12
|
+
= has_association.name
|
13
|
+
|
14
|
+
| :
|
15
|
+
|
16
|
+
= has_association.relationship_type
|
17
|
+
span.destination-join-type
|
18
|
+
= has_association.destination_join_type
|
19
|
+
span.destination-association-name
|
20
|
+
= has_association.opposite_name
|
21
|
+
|
22
|
+
i.glyphicon.glyphicon-triangle-right
|
23
|
+
= has_association.to_model.class_name
|
24
|
+
td
|
25
|
+
a.btn.btn-danger click="delete has_association" DELETE
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
form.form-horizontal
|
3
|
+
.form-group
|
4
|
+
label
|
5
|
+
.col-sm-2.control-label Join Type
|
6
|
+
.col-sm-10
|
7
|
+
view "select" content=model.join_types selectionBinding="model.has_association.join_type" class="form-control"
|
8
|
+
|
9
|
+
.form-group
|
10
|
+
label
|
11
|
+
.col-sm-2.control-label Source Model
|
12
|
+
.col-sm-10
|
13
|
+
view "select" content=model.models optionValuePath="content.id" optionLabelPath="content.class_name" selectionBinding="model.has_association.from_model" class="form-control"
|
14
|
+
|
15
|
+
.form-group
|
16
|
+
label
|
17
|
+
.col-sm-2.control-label Destination Model
|
18
|
+
.col-sm-10
|
19
|
+
view "select" content=model.models optionValuePath="content.id" optionLabelPath="content.class_name" selectionBinding="model.has_association.to_model" class="form-control"
|
20
|
+
|
21
|
+
.form-group
|
22
|
+
label
|
23
|
+
.col-sm-2.control-label
|
24
|
+
| Name
|
25
|
+
if model.has_association.source_is_defined
|
26
|
+
span.help-block #{model.has_association.from_model.class_name} has #{model.has_association.source_join_type}...
|
27
|
+
.col-sm-10
|
28
|
+
= input class="form-control" valueBinding="model.has_association.name"
|
29
|
+
|
30
|
+
.form-group
|
31
|
+
label
|
32
|
+
.col-sm-2.control-label
|
33
|
+
| Opposite Name
|
34
|
+
if model.has_association.destination_is_defined
|
35
|
+
span.help-block #{model.has_association.to_model.class_name} has #{model.has_association.destination_join_type}...
|
36
|
+
.col-sm-10
|
37
|
+
= input class="form-control" valueBinding="model.has_association.opposite_name"
|
38
|
+
|
39
|
+
.form-group
|
40
|
+
label
|
41
|
+
.col-sm-2.control-label
|
42
|
+
| Relationship Type
|
43
|
+
if model.has_association.models_are_defined
|
44
|
+
span.help-block #{model.has_association.from_model.class_name} ... #{model.has_association.to_model.class_name}
|
45
|
+
.col-sm-10
|
46
|
+
= input class="form-control" valueBinding="model.has_association.relationship_type"
|
47
|
+
|
48
|
+
.form-group
|
49
|
+
button.btn.btn-primary click="create model.has_association" Create Association
|
50
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
.form-group
|
3
|
+
label
|
4
|
+
.col-sm-2.control-label Class Name
|
5
|
+
.col-sm-10
|
6
|
+
= input class="form-control" valueBinding="model.model.class_name"
|
7
|
+
|
8
|
+
.form-group
|
9
|
+
label
|
10
|
+
.col-sm-2.control-label Inherits from
|
11
|
+
.col-sm-10
|
12
|
+
view "select" content=models optionValuePath="content.id" optionLabelPath="content.class_name" selectionBinding="model.model.superclass_model" class="form-control"
|
13
|
+
|
14
|
+
.properties.row
|
15
|
+
h2
|
16
|
+
| Properties
|
17
|
+
a.add.btn.btn-default click="add_property model.model" Add Property
|
18
|
+
|
19
|
+
each property in model.model.properties
|
20
|
+
.well.property.col-sm-6 class=property.isDirty:has-warning:
|
21
|
+
i.glyphicon.glyphicon-remove-circle.close.pull-right click="delete_property property"
|
22
|
+
|
23
|
+
.form-group
|
24
|
+
label
|
25
|
+
.col-sm-2.control-label Name
|
26
|
+
.col-sm-10
|
27
|
+
= focus-input valueBinding="property.name" class="form-control"
|
28
|
+
|
29
|
+
.form-group
|
30
|
+
label
|
31
|
+
.col-sm-2.control-label Type
|
32
|
+
.col-sm-10
|
33
|
+
view "select" content=property_types valueBinding="property.type" class="form-control"
|
34
|
+
|
35
|
+
.form-group
|
36
|
+
button.btn.btn-danger.pull-right click="delete model.model" DELETE!
|
37
|
+
|
38
|
+
.form-group
|
39
|
+
button.btn.btn-primary click="save model.model" Update
|
40
|
+
|
@@ -0,0 +1,8 @@
|
|
1
|
+
.row
|
2
|
+
div.col-sm-11
|
3
|
+
= input valueBinding="new_model_name" class="form-control" placeholder="Model Name" class="form-control"
|
4
|
+
a.btn.col-sm-1 click='add add_model_name'
|
5
|
+
i.glyphicon.glyphicon-plus
|
6
|
+
|
7
|
+
|
8
|
+
model-list node=model class="nested-list-group" id="model-list"
|
@@ -0,0 +1,113 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
*= require _bootstrap
|
4
|
+
*= require_self
|
5
|
+
*/
|
6
|
+
|
7
|
+
#accordion .glyphicon { margin-right:10px; }
|
8
|
+
|
9
|
+
#model-list {
|
10
|
+
margin-top: 4em;
|
11
|
+
}
|
12
|
+
|
13
|
+
|
14
|
+
label {
|
15
|
+
width: 100%;
|
16
|
+
}
|
17
|
+
|
18
|
+
[data-ember-action] {
|
19
|
+
cursor: pointer;
|
20
|
+
}
|
21
|
+
|
22
|
+
// Stolen and SCSSized from http://bootsnipp.com/snippets/featured/accordion-list-group-menu
|
23
|
+
.nested-list-group {
|
24
|
+
>.list-group {
|
25
|
+
.list-group-item:first-child {
|
26
|
+
border-top-right-radius: 0;
|
27
|
+
border-top-left-radius: 0;
|
28
|
+
}
|
29
|
+
.list-group-item {
|
30
|
+
border-width: 1px 0;
|
31
|
+
}
|
32
|
+
|
33
|
+
margin-bottom: 0;
|
34
|
+
}
|
35
|
+
.list-group-item {
|
36
|
+
border-radius:0;
|
37
|
+
}
|
38
|
+
|
39
|
+
.list-group .list-group {
|
40
|
+
margin: 0;
|
41
|
+
margin-top: 10px;
|
42
|
+
}
|
43
|
+
.list-group-item li.list-group-item {
|
44
|
+
margin: 0 -15px;
|
45
|
+
border-top: 1px solid #ddd;
|
46
|
+
border-bottom: 0;
|
47
|
+
padding-left: 30px;
|
48
|
+
&:last-child {padding-bottom: 0;}
|
49
|
+
}
|
50
|
+
|
51
|
+
div.list-group {
|
52
|
+
div.list-group {margin: 0;}
|
53
|
+
|
54
|
+
.list-group a.list-group-item {
|
55
|
+
border-top: 1px solid #ddd;
|
56
|
+
border-bottom: 0;
|
57
|
+
padding-left: 30px;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
$relationship-arrow-length: 60px;
|
63
|
+
|
64
|
+
#has-associations-table {
|
65
|
+
td {
|
66
|
+
line-height: 4em;
|
67
|
+
}
|
68
|
+
|
69
|
+
.relationship {
|
70
|
+
display: inline-block;
|
71
|
+
|
72
|
+
&:before {
|
73
|
+
content: '';
|
74
|
+
border: 1px solid black;
|
75
|
+
height: 1px;
|
76
|
+
width: $relationship-arrow-length;
|
77
|
+
display: inline-block;
|
78
|
+
position: relative;
|
79
|
+
margin: 5px;
|
80
|
+
}
|
81
|
+
|
82
|
+
&:after {
|
83
|
+
content: '';
|
84
|
+
border: 1px solid black;
|
85
|
+
height: 1px;
|
86
|
+
width: $relationship-arrow-length;
|
87
|
+
display: inline-block;
|
88
|
+
position: relative;
|
89
|
+
margin: 5px;
|
90
|
+
margin-right: -3px;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
.source-join-type {
|
95
|
+
position: absolute;
|
96
|
+
transform: translate(-$relationship-arrow-length - 5px,-14px);
|
97
|
+
}
|
98
|
+
|
99
|
+
.destination-join-type {
|
100
|
+
position: absolute;
|
101
|
+
transform: translate(5px,-14px);
|
102
|
+
}
|
103
|
+
|
104
|
+
.source-association-name {
|
105
|
+
position: absolute;
|
106
|
+
transform: translate(-$relationship-arrow-length - 5px,14px);
|
107
|
+
}
|
108
|
+
|
109
|
+
.destination-association-name {
|
110
|
+
position: absolute;
|
111
|
+
transform: translate(5px,14px);
|
112
|
+
}
|
113
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module MetaModel
|
2
|
+
module Meta
|
3
|
+
class HasAssociationsController < ApplicationController
|
4
|
+
before_action :get_has_association, only: [:edit, :show, :update, :destroy]
|
5
|
+
|
6
|
+
def index
|
7
|
+
render json: HasAssociation.all
|
8
|
+
end
|
9
|
+
|
10
|
+
def show
|
11
|
+
respond_to do |format|
|
12
|
+
format.json { render json: @has_association }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
has_association = HasAssociation.create(has_association_params)
|
18
|
+
|
19
|
+
create_models
|
20
|
+
|
21
|
+
render json: has_association
|
22
|
+
end
|
23
|
+
|
24
|
+
def destroy
|
25
|
+
@has_association.destroy
|
26
|
+
|
27
|
+
create_models
|
28
|
+
|
29
|
+
render json: nil
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def get_has_association
|
36
|
+
@has_association = HasAssociation.find(params[:id])
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_association_params
|
40
|
+
params.require(:has_association).permit(:join_type, :name, :opposite_name, :relationship_type, :from_model_id, :to_model_id)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|