neo4j-meta_model 0.0.1 → 0.1.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 +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
|
|