neo4j-meta_model 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.rdoc +19 -2
- data/app/assets/javascripts/meta_model.js.coffee +132 -130
- data/app/controllers/neo4j/meta_model/application_controller.rb +14 -0
- data/app/controllers/neo4j/meta_model/meta/has_associations_controller.rb +46 -0
- data/app/controllers/neo4j/meta_model/meta/models_controller.rb +82 -0
- data/app/controllers/neo4j/meta_model/meta/properties_controller.rb +38 -0
- data/app/controllers/neo4j/meta_model/meta_controller.rb +9 -0
- data/app/controllers/neo4j/meta_model/models_controller.rb +71 -0
- data/app/helpers/neo4j/meta_model/application_helper.rb +12 -0
- data/app/helpers/neo4j/meta_model/model_helper.rb +12 -0
- data/app/models/concerns/neo4j/meta_model/model_base.rb +45 -0
- data/app/models/neo4j/meta_model/has_association.rb +48 -0
- data/app/models/neo4j/meta_model/meta_model_base.rb +9 -0
- data/app/models/neo4j/meta_model/model.rb +53 -0
- data/app/models/neo4j/meta_model/property.rb +13 -0
- data/app/serializers/neo4j/meta_model/has_association_serializer.rb +15 -0
- data/app/serializers/neo4j/meta_model/model_serializer.rb +13 -0
- data/app/serializers/neo4j/meta_model/property_serializer.rb +8 -0
- data/app/views/{meta_model → neo4j/meta_model}/meta/associations/index.html.slim +0 -0
- data/app/views/{meta_model → neo4j/meta_model}/meta/index.html.slim +0 -0
- data/app/views/{meta_model → neo4j/meta_model}/meta/models/edit.html.slim +0 -0
- data/app/views/{meta_model → neo4j/meta_model}/models/_form.html.slim +16 -8
- data/app/views/{meta_model → neo4j/meta_model}/models/_has_many_association.html.slim +0 -0
- data/app/views/{meta_model → neo4j/meta_model}/models/_record_details.html.slim +0 -0
- data/app/views/{meta_model → neo4j/meta_model}/models/edit.html.slim +0 -0
- data/app/views/{meta_model → neo4j/meta_model}/models/index.html.slim +0 -0
- data/app/views/{meta_model → neo4j/meta_model}/models/meta_index.html.slim +0 -0
- data/app/views/{meta_model → neo4j/meta_model}/models/new.html.slim +0 -0
- data/app/views/{meta_model → neo4j/meta_model}/models/show.html.slim +0 -0
- data/config/routes.rb +1 -1
- data/lib/meta_models.rb +9 -7
- data/lib/neo4j/meta_model.rb +6 -0
- data/lib/neo4j/meta_model/engine.rb +25 -0
- data/lib/neo4j/meta_model/version.rb +5 -0
- data/test/dummy/config/application.rb +1 -1
- metadata +31 -31
- data/app/controllers/meta_model/application_controller.rb +0 -12
- data/app/controllers/meta_model/meta/has_associations_controller.rb +0 -44
- data/app/controllers/meta_model/meta/models_controller.rb +0 -80
- data/app/controllers/meta_model/meta/properties_controller.rb +0 -36
- data/app/controllers/meta_model/meta_controller.rb +0 -7
- data/app/controllers/meta_model/models_controller.rb +0 -69
- data/app/helpers/meta_model/application_helper.rb +0 -10
- data/app/helpers/meta_model/model_helper.rb +0 -10
- data/app/models/concerns/meta_model/model_base.rb +0 -43
- data/app/models/meta_model/has_association.rb +0 -46
- data/app/models/meta_model/meta_model_base.rb +0 -7
- data/app/models/meta_model/model.rb +0 -51
- data/app/models/meta_model/property.rb +0 -11
- data/app/serializers/meta_model/has_association_serializer.rb +0 -13
- data/app/serializers/meta_model/model_serializer.rb +0 -11
- data/app/serializers/meta_model/property_serializer.rb +0 -6
- data/lib/meta_model.rb +0 -4
- data/lib/meta_model/engine.rb +0 -23
- data/lib/meta_model/version.rb +0 -3
@@ -0,0 +1,38 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module MetaModel
|
3
|
+
module Meta
|
4
|
+
class PropertiesController < ApplicationController
|
5
|
+
before_action :get_property, only: [:edit, :show, :update, :destroy]
|
6
|
+
|
7
|
+
def destroy
|
8
|
+
@property.destroy
|
9
|
+
|
10
|
+
render json: nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def create
|
14
|
+
property = Property.create(property_params)
|
15
|
+
|
16
|
+
render json: property
|
17
|
+
end
|
18
|
+
|
19
|
+
def update
|
20
|
+
@property.update_attributes(property_params)
|
21
|
+
|
22
|
+
render json: @property
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def get_property
|
28
|
+
@property = Property.find(params[:id])
|
29
|
+
end
|
30
|
+
|
31
|
+
def property_params
|
32
|
+
model = params[:property].delete(:model_id)
|
33
|
+
params.require(:property).permit(:name, :type).merge(model: model)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module MetaModel
|
3
|
+
class ModelsController < ApplicationController
|
4
|
+
before_action :get_model
|
5
|
+
before_action :get_meta_model
|
6
|
+
before_action :get_record, only: [:show, :edit, :update]
|
7
|
+
|
8
|
+
layout 'layouts/meta_model'
|
9
|
+
def meta_index
|
10
|
+
@hierarchy = Model.order(:class_name).hierarchically
|
11
|
+
end
|
12
|
+
|
13
|
+
def index
|
14
|
+
@records = @model.all.to_a
|
15
|
+
respond_to do |format|
|
16
|
+
format.html
|
17
|
+
format.json { render json: @records, root: :records }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def show
|
22
|
+
end
|
23
|
+
|
24
|
+
def edit
|
25
|
+
end
|
26
|
+
|
27
|
+
def update
|
28
|
+
@record.update_attributes(params[:data])
|
29
|
+
|
30
|
+
redirect_to action: :show
|
31
|
+
end
|
32
|
+
|
33
|
+
def new
|
34
|
+
@record = @model.new
|
35
|
+
end
|
36
|
+
|
37
|
+
def create
|
38
|
+
record = @model.create(params[:data])
|
39
|
+
|
40
|
+
redirect_to action: :show, id: record.id
|
41
|
+
end
|
42
|
+
|
43
|
+
def destroy
|
44
|
+
@record.destroy
|
45
|
+
|
46
|
+
redirect_to action: :index, model: params[:model]
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def get_record
|
52
|
+
@record = @model.find(params[:id])
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_meta_model
|
56
|
+
@meta_model = Model.where(class_name: model_param_class_name).first if model_param_class_name
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_model
|
60
|
+
@model = "Neo4j::MetaModel::#{model_param_class_name}".constantize if model_param_class_name
|
61
|
+
end
|
62
|
+
|
63
|
+
def model_param_class_name
|
64
|
+
if params[:model]
|
65
|
+
@model_param_class_name ||= params[:model].classify
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module MetaModel
|
3
|
+
module ApplicationHelper
|
4
|
+
def action_and_controller_javascript_include_tag
|
5
|
+
capture do
|
6
|
+
concat javascript_include_tag controller_path if Rails.root.join("app/assets/javascripts/#{controller_path}.js.coffee").exist?
|
7
|
+
concat javascript_include_tag "#{controller_path}/#{action_name}" if Rails.root.join("app/assets/javascripts/#{controller_path}/#{action_name}.js.coffee").exist?
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module MetaModel
|
3
|
+
module ModelHelper
|
4
|
+
def hierarchical_render(hierarchy, level = 0, &block)
|
5
|
+
hierarchy.each do |object, sub_hierarchy|
|
6
|
+
block.call object, level
|
7
|
+
hierarchical_render(sub_hierarchy, level + 1, &block)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module MetaModel
|
3
|
+
module ModelBase
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
LOADED_CLASSES = []
|
7
|
+
included do |base|
|
8
|
+
LOADED_CLASSES << self
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def inherited(base)
|
13
|
+
LOADED_CLASSES << base
|
14
|
+
end
|
15
|
+
|
16
|
+
def meta_model_class
|
17
|
+
name.gsub(/^Neo4j::MetaModel::/, '')
|
18
|
+
end
|
19
|
+
|
20
|
+
def naming_column
|
21
|
+
# Probably want to allow the user to choose this
|
22
|
+
Neo4j::MetaModel::Model.where(class_name: meta_model_class).first.properties.detect {|p| p.type == 'String' }.name
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def naming_column_value
|
27
|
+
self.read_attribute(self.class.naming_column)
|
28
|
+
end
|
29
|
+
|
30
|
+
def meta_model_class
|
31
|
+
self.class.meta_model_class
|
32
|
+
end
|
33
|
+
|
34
|
+
def association_values
|
35
|
+
self.class.associations.each_with_object({}) do |(key, _), result|
|
36
|
+
result[key] = self.send(key)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def _description
|
41
|
+
self.try(:name) || self.try(:title) || self.try(:description) || self.id
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module MetaModel
|
3
|
+
class HasAssociation
|
4
|
+
include Neo4j::ActiveRel
|
5
|
+
|
6
|
+
from_class 'Neo4j::MetaModel::Model'
|
7
|
+
to_class 'Neo4j::MetaModel::Model'
|
8
|
+
type 'has_association_to'
|
9
|
+
|
10
|
+
|
11
|
+
# one_to_many refers to from_class has_many to_classes
|
12
|
+
# many_to_one refers to from_class has_one to_class
|
13
|
+
property :join_type, type: String
|
14
|
+
validates_inclusion_of :join_type, :in => %w( many_to_one one_to_many many_to_many )
|
15
|
+
|
16
|
+
# Name of associations on each side
|
17
|
+
property :name, type: String
|
18
|
+
property :opposite_name, type: String
|
19
|
+
|
20
|
+
property :relationship_type, type: String
|
21
|
+
|
22
|
+
def from_model
|
23
|
+
from_node
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_model
|
27
|
+
to_node
|
28
|
+
end
|
29
|
+
|
30
|
+
def from_model=(other)
|
31
|
+
self.from_node = other
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_model=(other)
|
35
|
+
self.to_node = other
|
36
|
+
end
|
37
|
+
|
38
|
+
def from_model_id=(id)
|
39
|
+
self.from_model = Model.find(id)
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_model_id=(id)
|
43
|
+
self.to_model = Model.find(id)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module MetaModel
|
3
|
+
class Model < MetaModelBase
|
4
|
+
property :class_name, type: String
|
5
|
+
|
6
|
+
has_one :out, :superclass_model, type: :inherits_from, model_class: 'Neo4j::MetaModel::Model'
|
7
|
+
|
8
|
+
has_one :out, :id_property, type: :has_id_property, model_class: 'Neo4j::MetaModel::Property'
|
9
|
+
has_many :out, :properties, type: :has_property, model_class: 'Neo4j::MetaModel::Property'
|
10
|
+
|
11
|
+
has_many :both, :assocs, model_class: 'Neo4j::MetaModel::Model', rel_class: 'Neo4j::MetaModel::HasAssociation'
|
12
|
+
|
13
|
+
before_destroy :destroy_properties
|
14
|
+
|
15
|
+
def to_param
|
16
|
+
self.class_name.tableize
|
17
|
+
end
|
18
|
+
|
19
|
+
# def property_ids
|
20
|
+
# properties(:p).pluck(p: :uuid)
|
21
|
+
# end
|
22
|
+
|
23
|
+
def has_associations
|
24
|
+
assocs.each_rel.to_a
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.hierarchically
|
28
|
+
Hash.new.tap do |result|
|
29
|
+
model_parents = Hash[*all.query_as(:model).optional_match("model-[:inherits_from]->(parent)").pluck(:model, :parent).flatten]
|
30
|
+
|
31
|
+
all.query_as(:model).where('NOT(model-[:inherits_from]->())').pluck(:model).each do |model|
|
32
|
+
result[model] = {}
|
33
|
+
end
|
34
|
+
|
35
|
+
all.query_as(:model).match('p=model-[:inherits_from*1..]->()').pluck('nodes(p)').each do |path|
|
36
|
+
path.reverse.inject(result) do |sub_result, model|
|
37
|
+
sub_result[model] ||= {}
|
38
|
+
sub_result[model]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def destroy_properties
|
48
|
+
properties.each(&:destroy)
|
49
|
+
id_property.try(:destroy)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module MetaModel
|
3
|
+
class Property < MetaModelBase
|
4
|
+
property :name, type: String
|
5
|
+
property :type, type: String
|
6
|
+
|
7
|
+
validates_inclusion_of :type, :in => %w( String DateTime Boolean Integer )
|
8
|
+
|
9
|
+
has_one :in, :model, origin: :properties, model_class: 'Neo4j::MetaModel::Model'
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module MetaModel
|
3
|
+
class HasAssociationSerializer < ActiveModel::Serializer
|
4
|
+
attributes :id, :join_type, :name, :opposite_name, :relationship_type, :from_model, :to_model
|
5
|
+
|
6
|
+
def from_model
|
7
|
+
object.from_node.id
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_model
|
11
|
+
object.to_node.id
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -9,15 +9,17 @@
|
|
9
9
|
.col-sm-10
|
10
10
|
- case association.type
|
11
11
|
- when :has_one
|
12
|
-
= select_tag "data[#{key}]", options_from_collection_for_select(association.target_class.all.to_a, :id, :naming_column_value, record.send(key).id), class: 'form-control'
|
12
|
+
= select_tag "data[#{key}]", options_from_collection_for_select(association.target_class.all.to_a, :id, :naming_column_value, record.send(key).try(:id)), include_blank: 'Select one from the options below', class: 'form-control'
|
13
13
|
- when :has_many
|
14
14
|
.has-many-association data-option-type="#{association.target_class.meta_model_class.tableize.singularize}" data-options="#{association.target_class.all.to_json(methods: :naming_column_value)}"
|
15
15
|
select.form-control rv-on-change="view.add"
|
16
|
-
option
|
16
|
+
option Select from the options below to add to the list
|
17
17
|
option rv-each-option="view.current_options < objects" rv-value="option.id"
|
18
18
|
| { option.naming_column_value }
|
19
19
|
|
20
|
-
.list
|
20
|
+
.help-block Click to remove an item from the list
|
21
|
+
|
22
|
+
.list-group data-object-ids="#{record.send(key).map(&:id).to_json}"
|
21
23
|
a.list-group-item rv-each-object="objects < objects" rv-data-id="object.id" rv-on-click="view.delete"
|
22
24
|
input type="hidden" name="data[#{key}][]" rv-value="object.id"
|
23
25
|
| { object.naming_column_value }
|
@@ -31,11 +33,18 @@ coffee:
|
|
31
33
|
|
32
34
|
initialize: ->
|
33
35
|
el = $(@el)
|
34
|
-
@options = _(el.data('options')).map((element) ->
|
35
|
-
element[el.data('option-type')]
|
36
|
-
).value()
|
37
36
|
|
38
|
-
@objects = [
|
37
|
+
@objects = []
|
38
|
+
object_ids = el.find('.list-group').data('object-ids')
|
39
|
+
|
40
|
+
@options = _(el.data('options')).map((element) =>
|
41
|
+
e = element[el.data('option-type')]
|
42
|
+
|
43
|
+
if e.id in object_ids
|
44
|
+
@objects.push e
|
45
|
+
|
46
|
+
e
|
47
|
+
).value()
|
39
48
|
|
40
49
|
render: ->
|
41
50
|
@binding = rivets.bind $(@el), {@objects, view: @}
|
@@ -46,7 +55,6 @@ coffee:
|
|
46
55
|
@binding.unbind()
|
47
56
|
|
48
57
|
current_options: =>
|
49
|
-
console.log('current_options!');
|
50
58
|
_(@options).difference(@objects).value()
|
51
59
|
|
52
60
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/config/routes.rb
CHANGED
data/lib/meta_models.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'ext/hash.rb'
|
2
2
|
|
3
3
|
def create_models
|
4
|
-
models = MetaModel::Model.hierarchically.to_a_recursive.flatten
|
4
|
+
models = Neo4j::MetaModel::Model.hierarchically.to_a_recursive.flatten
|
5
5
|
|
6
|
-
MetaModel::ModelBase::LOADED_CLASSES.each do |loaded_class|
|
6
|
+
Neo4j::MetaModel::ModelBase::LOADED_CLASSES.each do |loaded_class|
|
7
7
|
loaded_namespace, loaded_class = loaded_class.name.to_s.reverse.split('::', 2).reverse.map(&:reverse)
|
8
8
|
|
9
9
|
namespace = loaded_namespace.blank? ? Object : loaded_namespace.constantize
|
@@ -11,12 +11,13 @@ def create_models
|
|
11
11
|
namespace.send(:remove_const, loaded_class.to_sym)
|
12
12
|
end
|
13
13
|
|
14
|
-
MetaModel::ModelBase::LOADED_CLASSES.clear
|
14
|
+
Neo4j::MetaModel::ModelBase::LOADED_CLASSES.clear
|
15
15
|
|
16
16
|
models.each do |model|
|
17
|
-
code = "module
|
17
|
+
code = "module Neo4j\n"
|
18
|
+
code << "module MetaModel\n"
|
18
19
|
code << "class #{model.class_name}"
|
19
|
-
code << " < MetaModel::#{model.superclass_model.class_name}" if model.superclass_model
|
20
|
+
code << " < Neo4j::MetaModel::#{model.superclass_model.class_name}" if model.superclass_model
|
20
21
|
code << "\n"
|
21
22
|
|
22
23
|
code << " include Neo4j::ActiveNode\n"
|
@@ -31,7 +32,7 @@ def create_models
|
|
31
32
|
model.assocs.each_with_rel do |other_model, rel|
|
32
33
|
# Primary association
|
33
34
|
if rel.from_node.class_name == model.class_name
|
34
|
-
options = {type: rel.relationship_type, model_class: 'MetaModel::' + other_model.class_name}
|
35
|
+
options = {type: rel.relationship_type, model_class: 'Neo4j::MetaModel::' + other_model.class_name}
|
35
36
|
|
36
37
|
has_type = case rel.join_type
|
37
38
|
when 'many_to_many', 'many_to_one'
|
@@ -45,7 +46,7 @@ def create_models
|
|
45
46
|
|
46
47
|
# Reverse association
|
47
48
|
if rel.to_node.class_name == model.class_name
|
48
|
-
options = {model_class: 'MetaModel::' + other_model.class_name, origin: rel.name}
|
49
|
+
options = {model_class: 'Neo4j::MetaModel::' + other_model.class_name, origin: rel.name}
|
49
50
|
|
50
51
|
has_type = case rel.join_type
|
51
52
|
when 'many_to_many', 'one_to_many'
|
@@ -59,6 +60,7 @@ def create_models
|
|
59
60
|
|
60
61
|
end
|
61
62
|
|
63
|
+
code << "end\n"
|
62
64
|
code << "end\n"
|
63
65
|
code << "end"
|
64
66
|
|