rails_age 0.4.1 → 0.5.2

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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -10
  3. data/README.md +7 -4
  4. data/lib/apache_age/validators/{unique_edge_validator.rb → unique_edge.rb} +8 -4
  5. data/lib/apache_age/validators/{unique_vertex_validator.rb → unique_vertex.rb} +7 -3
  6. data/lib/generators/apache_age/edge/USAGE +18 -15
  7. data/lib/generators/apache_age/edge/edge_generator.rb +14 -41
  8. data/lib/generators/apache_age/edge/templates/edge.rb.tt +22 -14
  9. data/lib/generators/apache_age/generator_entity_helpers.rb +84 -0
  10. data/lib/generators/apache_age/generator_resource_helpers.rb +6 -0
  11. data/lib/generators/apache_age/node/USAGE +7 -7
  12. data/lib/generators/apache_age/node/node_generator.rb +9 -82
  13. data/lib/generators/apache_age/node/templates/node.rb.tt +2 -2
  14. data/lib/generators/apache_age/scaffold_node/USAGE +16 -0
  15. data/lib/generators/apache_age/scaffold_node/scaffold_node_generator.rb +68 -0
  16. data/lib/generators/apache_age/scaffold_node/templates/node_controller.rb.tt +50 -0
  17. data/lib/generators/apache_age/scaffold_node/templates/views/_form.html.erb copy.tt +37 -0
  18. data/lib/generators/apache_age/scaffold_node/templates/views/_form.html.erb.tt +37 -0
  19. data/lib/generators/apache_age/scaffold_node/templates/views/edit.html.erb copy.tt +12 -0
  20. data/lib/generators/apache_age/scaffold_node/templates/views/edit.html.erb.tt +12 -0
  21. data/lib/generators/apache_age/scaffold_node/templates/views/index.html.erb copy.tt +16 -0
  22. data/lib/generators/apache_age/scaffold_node/templates/views/index.html.erb.tt +16 -0
  23. data/lib/generators/apache_age/scaffold_node/templates/views/new.html.erb copy.tt +11 -0
  24. data/lib/generators/apache_age/scaffold_node/templates/views/new.html.erb.tt +11 -0
  25. data/lib/generators/apache_age/scaffold_node/templates/views/partial.html.erb copy.tt +17 -0
  26. data/lib/generators/apache_age/scaffold_node/templates/views/partial.html.erb.tt +17 -0
  27. data/lib/generators/apache_age/scaffold_node/templates/views/show.html.erb copy.tt +10 -0
  28. data/lib/generators/apache_age/scaffold_node/templates/views/show.html.erb.tt +10 -0
  29. data/lib/rails_age/version.rb +1 -1
  30. data/lib/rails_age.rb +2 -2
  31. metadata +21 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03e419984be6f29b1da74d0de6e31ccb218ba966e3818537884fcff715024e02
4
- data.tar.gz: cb5a30c1e17ee7bf30394691232e3185e317ef5e827ece3ab02ef7d14cb0aef5
3
+ metadata.gz: d54712ca67a303ffa92d78165d30a500b1f695be6176b3198e7ff3f9f60ab4f9
4
+ data.tar.gz: 8f8f999c42777dc432bf543b6256852d10a0fbcbcd4fe33ad06817277a47bb5d
5
5
  SHA512:
6
- metadata.gz: 555b80c544a8d5217d5c40ef3f24c15cd8fbf0c13bf96d1445845d9afc21d5e2ab835a60ac678ba5177fa5562ef1b87d7f293226783c94f1470d8b64e7a56fd9
7
- data.tar.gz: 303f2776ebc5320711f50ec54e9a136ba7d9727fcb28c8d0038ffdcb0edb94d6715b93f40598a70d3eb3b8f1405a05610a707458f91209288414f0a4a7251374
6
+ metadata.gz: 75c804a5b29705a18344ea70d9a799ea3578d90055b056ba48b70984132f2fbd04bdd906ac744e2a587fe095e9a8e112d773ecc84cf6325be192c212d769090d
7
+ data.tar.gz: 932a6c5843243a23ef48b69e87f0fef940030c9e47ce652be141bc6efb45a8cbde04c191853b3d15e754e3ee71d7033b301ab6432982c1fc357250fceb892f02
data/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- ## VERSION 0.5.1 - 2024-xx-xx
3
+ ## VERSION 0.6.2 - 2024-xx-xx
4
4
 
5
5
  - **cypher queries** (like active record queries)
6
6
  * schema override
@@ -8,32 +8,49 @@
8
8
  * paths support
9
9
  * select attributes support
10
10
 
11
- ## VERSION 0.5.0 - 2024-xx-xx
11
+ ## VERSION 0.6.1 - 2024-xx-xx
12
12
 
13
13
  - **Age Path**
14
14
 
15
- ## VERSION 0.4.3 - 2024-xx-xx
15
+ ## VERSION 0.6.0 - 2024-xx-xx
16
+
17
+ breaking change?: namespaces (by default) will use their own schema? (add to database.yml & schema.rb ?)
16
18
 
17
19
  - **AGE Schema override**
18
20
 
19
21
  - **multiple AGE Schema**
20
22
 
21
- ## VERSION 0.4.3 - 2024-xx-xx
23
+ ## VERSION 0.5.3 - 2024-xx-xx
22
24
 
23
25
  - **Edge Scaffold** (generates edge, type, view and controller)
24
26
  * add `rails generate apache_age:edge_scaffold HasJob employee_role start_node:person end_node:company`
25
27
 
26
- ## VERSION 0.4.2 - 2024-xx-xx
28
+ ## VERSION 0.5.2 - 2024-xx-xx
29
+
30
+ - **Edge Generator**
31
+ * add start-/end-nodes types to edge generator (would make scaffold easier), ie:
32
+ `rails generate apache_age:edge HasPet owner_role start_node:person end_node:pet`
33
+ with property and specified start-/end-nodes (person and pet nodes must have already been created)
34
+
35
+ ## VERSION 0.5.2 - 2024-06-16
36
+
37
+ - **Node Scaffold** (generates node, type, view and controller)
38
+ * add `rails generate apache_age:node_scaffold Person first_name last_name age:integer`
39
+
40
+ ## VERSION 0.5.1 - 2024-06-16
41
+
42
+ **yanked** (2024-06-16) - had an issue with the generator
27
43
 
28
44
  - **Node Scaffold** (generates node, type, view and controller)
29
45
  * add `rails generate apache_age:node_scaffold Person first_name last_name age:integer`
30
46
 
31
- ## VERSION 0.4.2 - 2024-xx-xx
47
+ ## VERSION 0.5.0 - 2024-06-15
48
+
49
+ **breaking change**: renamed the validators to UniqueVertex and UniqueEdge
32
50
 
33
51
  - **Edge Generator**
34
- * add `rails generate apache_age:edge HasPet owner_role` just a property
35
- * add `rails generate apache_age:edge HasPet owner_role start_node:person end_node:pet`
36
- with property and specified start-/end-nodes (person and pet nodes must have already been created)
52
+ * add `rails generate apache_age:edge HasPet owner_role`
53
+ caveate: start_node and end_node are of type `:vertex` in the generator but can be changed manually in the class file - having trouble with the generator loading the types (the generator rejects custom types - but rails still works with custom types)
37
54
 
38
55
  ## VERSION 0.4.1 - 2024-06-15
39
56
 
@@ -43,7 +60,7 @@
43
60
 
44
61
  ## VERSION 0.4.0 - 2024-06-14
45
62
 
46
- Minor breaking change: type (:vertix) is now required in core for edges
63
+ **breaking change**: type (:vertix) is now required in core for edges
47
64
 
48
65
  - **Installer**
49
66
  * AGE types added to installer (with tests)
data/README.md CHANGED
@@ -55,8 +55,11 @@ install Apache Age (you can ignore the `unknown OID` warnings)
55
55
  bundle add rails_age
56
56
  bundle install
57
57
  bin/rails apache_age:install
58
+ # optional: prevents `bin/rails db:migrate` from modifying the schema file,
59
+ # alternatively you can use: `bin/rails apache_age:migrate` to run safe migrations
60
+ bin/rails apache_age:override_db_migrate
58
61
  git add .
59
- git commit -m "Add Apache Age to Rails"
62
+ git commit -m "Add & configure Apache Age within Rails"
60
63
  ```
61
64
 
62
65
  make some nodes :string is the default type
@@ -69,10 +72,10 @@ make some edges (`:vertex` is the default type) for start_node and end_node
69
72
  ```bash
70
73
  # when start node and end node are not specified they are of type `:vertex`
71
74
  # this is generally not recommended - exept when very generic relationships are needed
72
- rails generate apache_age:edge HasJob employee_role
75
+ rails generate apache_age:edge HasJob employee_role begin_date:date
73
76
 
74
- # this is recommended - use explicit start_node and end_node types
75
- rails generate apache_age:node HasPet start_node:person end_node:pet caretaker_role
77
+ # # this is recommended - (but not yet working) add explicit start_node and end_node types manually
78
+ # rails generate apache_age:node HasPet start_node:person end_node:pet caretaker_role
76
79
  ```
77
80
 
78
81
  **NOTE:** the default `rails db:migrate` inappropriately modifies the schema file. This installer patches the migration to prevent this (however this might break on rails updates, etc). **You can run `bin/rails apache_age:install` at any time to repair the schema file as needed.**
@@ -1,10 +1,14 @@
1
+ # lib/apache_age/validators/unique_edge.rb
2
+
1
3
  # Usage (within an Age Model)
2
- # validates_with UniqueEdgeValidator, attributes: [:employee_role, :start_node, :end_node]
3
- # validates_with UniqueEdgeValidator, attributes: [:start_id, :employee_role, :end_id]
4
- #
4
+ # validates_with(
5
+ # ApacheAge::Validators::UniqueEdge,
6
+ # attributes: [:start_id, :employee_role, :end_id]
7
+ # )
8
+
5
9
  module ApacheAge
6
10
  module Validators
7
- class UniqueEdgeValidator < ActiveModel::Validator
11
+ class UniqueEdge < ActiveModel::Validator
8
12
  def validate(record)
9
13
  allowed_keys = record.age_properties.keys
10
14
  attributes = options[:attributes] || []
@@ -1,10 +1,14 @@
1
+ # lib/apache_age/validators/unique_vertex.rb
2
+
1
3
  # Usage (within an Age Model)
2
- # validates_with UniqueVertexValidator, attributes: [:first_name, :last_name, :gender]
4
+ # validates_with(
5
+ # ApacheAge::Validators::UniqueVertex,
6
+ # attributes: [:first_name, :last_name, :gender]
7
+ # )
3
8
 
4
- # lib/apache_age/validators/unique_vertex_validator.rb
5
9
  module ApacheAge
6
10
  module Validators
7
- class UniqueVertexValidator < ActiveModel::Validator
11
+ class UniqueVertex < ActiveModel::Validator
8
12
  def validate(record)
9
13
  allowed_keys = record.age_properties.keys
10
14
  attributes = options[:attributes]
@@ -1,35 +1,38 @@
1
1
  Description:
2
- This creates Apache AGE nodes that work seamlessly with Rails.
3
- A node can be created with or without a namespace.
2
+ This creates Apache AGE edges that work seamlessly with Rails.
3
+ An edge can be created with or without a namespace.
4
4
  See the below examples.
5
5
 
6
6
  Example:
7
- `bin/rails g apache_age:node Cat name age:integer`
7
+ `bin/rails g apache_age:edge HasJob employee_role start_date:date`
8
+
9
+ (hopefully comming soon - but not yet ready is the ability to add start_node and end_node types)
10
+ `bin/rails g apache_age:edge HasJob employee_role start_date:date start_node:person end_node:company`
8
11
 
9
12
  This creates:
10
- `app/nodes/cat.rb`
13
+ `app/edges/has_job.rb`
11
14
 
12
15
  with the contents:
13
16
  ```
14
- class Cat
15
- include ApacheAge::Entities::Vertex
17
+ class HasJob
18
+ include ApacheAge::Entities::Edge
16
19
 
17
- attribute :name, :string
18
- attribute :age, :integer
20
+ attribute :employee_role, :string
21
+ attribute :start_date, :date
19
22
 
20
- validates :name, presence: true
21
- validates :age, presence: true
23
+ validates :employee_role, presence: true
24
+ validates :begin_date, presence: true
22
25
 
23
26
  # unique node validator (remove any attributes that are not important to uniqueness)
24
27
  validates_with(
25
- ApacheAge::Validators::UniqueVertexValidator,
26
- attributes: [:name, :age]
28
+ ApacheAge::Validators::UniqueVertex,
29
+ attributes: [:employee_role, :begin_date :start_node, :end_node]
27
30
  )
28
31
  end
29
32
  ```
30
33
 
31
34
  A namespace can also be used:
32
- `bin/rails g apache_age:node Animals/Cat name age:integer`
35
+ `bin/rails g apache_age:edge Animals/Cat name age:integer`
33
36
 
34
37
  This creates:
35
38
  `app/nodes/animals/cat.rb`
@@ -47,8 +50,8 @@ Example:
47
50
 
48
51
  # unique node validator (remove any attributes that are not important to uniqueness)
49
52
  validates_with(
50
- ApacheAge::Validators::UniqueVertexValidator,
51
- attributes: [:name, :age]
53
+ ApacheAge::Validators::UniqueVertex,
54
+ attributes: [:name, :age, :start_node, :end_node]
52
55
  )
53
56
  end
54
57
  ```
@@ -1,56 +1,29 @@
1
+ # lib/generators/apache_age/edge/edge_generator.rb
1
2
  require 'rails/generators'
2
3
  require 'rails/generators/named_base'
3
4
 
5
+ require_relative '../generator_entity_helpers'
6
+ # TODO: get generators to work with custom types!
7
+ # require_relative "#{Rails.root}/config/initializers/types"
8
+
4
9
  module ApacheAge
5
10
  class EdgeGenerator < Rails::Generators::NamedBase
11
+ include ApacheAge::GeneratorEntityHelpers
12
+
13
+ desc "Generates edge (model) with attributes."
14
+
6
15
  source_root File.expand_path('templates', __dir__)
7
16
  argument :attributes, type: :array, default: [], banner: "field:type field:type"
8
17
 
9
18
  def perform_task
10
- behavior == :invoke ? create_edge_file : destroy_edge_file
19
+ age_type = 'edge'
20
+ Rails.application.eager_load! # Ensure all initializers and dependencies are loaded
21
+ behavior == :invoke ? generate_age_entity(age_type) : destroy_age_entity(age_type)
11
22
  end
12
23
 
13
24
  private
14
25
 
15
- def create_edge_file
16
- template "edge.rb.tt", File.join("app/edge", class_path, "#{file_name}.rb")
17
- end
18
-
19
- def destroy_edge_file
20
- file_path = File.join("app/edge", class_path, "#{file_name}.rb")
21
- File.delete(file_path) if File.exist?(file_path)
22
- end
23
-
24
- def attributes_list
25
- attributes.map { |attr| { name: attr.name, type: attr.type } }
26
- end
27
-
28
- def unique_attributes
29
- attributes_list.map { |attr| attr[:name].to_sym }
30
- end
31
-
32
- def parent_module
33
- class_path.map(&:camelize).join('::')
34
- end
35
-
36
- def full_class_name
37
- parent_module.empty? ? class_name : "#{parent_module}::#{class_name}"
38
- end
39
-
40
- def indented_namespace
41
- return '' if parent_module.empty?
42
-
43
- parent_module.split('::').map.with_index do |namespace, index|
44
- "#{' ' * index}module #{namespace}"
45
- end.join("\n") + "\n"
46
- end
47
-
48
- def indented_end_namespace
49
- return '' if parent_module.empty?
50
-
51
- parent_module.split('::').map.with_index do |_, index|
52
- "#{' ' * (parent_module.split('::').length - 1 - index)}end"
53
- end.join("\n") + "\n"
54
- end
26
+ # different than node_generator.rb
27
+ def unique_edge_attributes = unique_attributes + [:start_node, :end_node]
55
28
  end
56
29
  end
@@ -1,20 +1,28 @@
1
- <%= indented_namespace %>
2
- <%= ' ' * class_path.length %>class <%= class_name %>
3
- <%= ' ' * class_path.length %> include ApacheAge::Entities::Edge
1
+ class <%= class_name %>
2
+ include ApacheAge::Entities::Edge
4
3
 
5
4
  <%- attributes_list.each do |attribute| -%>
6
- <%= ' ' * class_path.length %> attribute :<%= attribute[:name] %>, :<%= attribute[:reference] || attribute[:type] %>
5
+ attribute :<%= attribute[:name] %>, :<%= attribute[:reference] || attribute[:type] %>
7
6
  <%- end -%>
7
+ # recommendation for (start_node and end_node): change `:vertex` with the 'node' type
8
+ # see `config/initializers/apache_age.rb` for the list of available node types
9
+ attribute :start_node, :vertex
10
+ attribute :end_node, :vertex
8
11
 
9
- <%= ' ' * class_path.length %> validates :<%= unique_attributes.first %>, presence: true
10
- <%= ' ' * class_path.length %> validate :validate_unique
12
+ <%- attributes_list.each do |attribute| -%>
13
+ validates :<%= attribute[:name] %>, presence: true
14
+ <%- end -%>
15
+ validates :start_node, presence: true
16
+ validates :end_node, presence: true
17
+
18
+ validate :validate_unique_edge
11
19
 
12
- <%= ' ' * class_path.length %> private
20
+ private
13
21
 
14
- <%= ' ' * class_path.length %> def validate_unique
15
- <%= ' ' * class_path.length %> ApacheAge::Validators::UniqueEdgeValidator
16
- <%= ' ' * class_path.length %> .new(attributes: <%= unique_attributes.inspect %>)
17
- <%= ' ' * class_path.length %> .validate(self)
18
- <%= ' ' * class_path.length %> end
19
- <%= ' ' * class_path.length %>end
20
- <%= indented_end_namespace %>
22
+ # custom unique edge validator (remove any attributes that are NOT important to uniqueness)
23
+ def validate_unique_edge
24
+ ApacheAge::Validators::UniqueEdge
25
+ .new(attributes: <%= unique_edge_attributes.inspect %>)
26
+ .validate(self)
27
+ end
28
+ end
@@ -0,0 +1,84 @@
1
+ # lib/generators/apache_age/generator_entity_helpers.rb
2
+
3
+ module ApacheAge
4
+ module GeneratorEntityHelpers
5
+ def generate_age_entity(age_type)
6
+ template "#{age_type}.rb.tt", File.join(destination_root, "app/#{age_type}s", class_path, "#{file_name}.rb")
7
+ add_type_config
8
+ end
9
+
10
+ def destroy_age_entity(age_type)
11
+ file_path = File.join(destination_root, "app/#{age_type}s", class_path, "#{file_name}.rb")
12
+ File.delete(file_path) if File.exist?(file_path)
13
+ remove_type_config
14
+ end
15
+
16
+ def attributes_list
17
+ attributes.map { |attr| { name: attr.name, type: attr.type } }
18
+ end
19
+
20
+ def parent_module
21
+ class_path.map(&:camelize).join('::')
22
+ end
23
+
24
+ def unique_attributes
25
+ attributes_list.map { |attr| attr[:name].to_sym }
26
+ end
27
+
28
+ def full_class_name
29
+ parent_module.empty? ? class_name : "#{parent_module}::#{class_name}"
30
+ end
31
+
32
+ def indented_namespace
33
+ return '' if parent_module.empty?
34
+
35
+ parent_module.split('::').map.with_index do |namespace, index|
36
+ "#{' ' * index}module #{namespace}"
37
+ end.join("\n") + "\n"
38
+ end
39
+
40
+ # def indented_end_namespace
41
+ # return '' if parent_module.empty?
42
+
43
+ # parent_module.split('::').map.with_index do |_, index|
44
+ # "#{' ' * (parent_module.split('::').length - 1 - index)}end"
45
+ # end.join("\n") + "\n"
46
+ # end
47
+
48
+ def add_type_config
49
+ return unless File.exist?(types_config_file)
50
+
51
+ types_content = File.read(types_config_file)
52
+ types_content.sub!(/^end\s*$/, "#{new_type_content}end")
53
+ File.open(types_config_file, 'w') { |file| file.write(types_content) }
54
+ puts " modified: config/initializers/types.rb"
55
+ end
56
+
57
+ def remove_type_config
58
+ return unless File.exist?(types_config_file)
59
+
60
+ type_to_remove = new_type_content
61
+
62
+ types_content = File.read(types_config_file)
63
+ types_content.gsub!(type_to_remove, '')
64
+ File.open(types_config_file, 'w') { |file| file.write(types_content) }
65
+ end
66
+
67
+ def types_config_file = File.join(Rails.root, 'config/initializers/types.rb')
68
+
69
+ def new_type_content
70
+ file_path = [class_path, file_name].reject(&:blank?).join('/').downcase
71
+ entity_namespace = class_path.map(&:capitalize).join('::')
72
+ entity_class_name = file_name.split('_').map(&:capitalize).join
73
+ entity_namespaced_class = [entity_namespace, entity_class_name].reject(&:blank?).join('::')
74
+ type_name = [class_path.join('_'), file_name].reject(&:blank?).join('_')
75
+ content =
76
+ <<-RUBY
77
+ require_dependency '#{file_path}'
78
+ ActiveModel::Type.register(
79
+ :#{type_name}, ApacheAge::Types::AgeTypeGenerator.create_type_for(#{entity_namespaced_class})
80
+ )
81
+ RUBY
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,6 @@
1
+ module ApacheAge
2
+ # Some helpers for generating scaffolding
3
+ module GeneratorResourceHelpers
4
+
5
+ end
6
+ end
@@ -14,16 +14,16 @@ Example:
14
14
  class Cat
15
15
  include ApacheAge::Entities::Vertex
16
16
 
17
- attribute :name, :string
18
- attribute :age, :integer
17
+ attribute :full_name, :string
18
+ attribute :birthdate, :date
19
19
 
20
- validates :name, presence: true
21
- validates :age, presence: true
20
+ validates :full_name, presence: true
21
+ validates :birthdate, presence: true
22
22
 
23
23
  # unique node validator (remove any attributes that are not important to uniqueness)
24
24
  validates_with(
25
- ApacheAge::Validators::UniqueVertexValidator,
26
- attributes: [:name, :age]
25
+ ApacheAge::Validators::UniqueVertex,
26
+ attributes: [:full_name, :birthdate]
27
27
  )
28
28
  end
29
29
  ```
@@ -47,7 +47,7 @@ Example:
47
47
 
48
48
  # unique node validator (remove any attributes that are not important to uniqueness)
49
49
  validates_with(
50
- ApacheAge::Validators::UniqueVertexValidator,
50
+ ApacheAge::Validators::UniqueVertex,
51
51
  attributes: [:name, :age]
52
52
  )
53
53
  end
@@ -1,94 +1,21 @@
1
+ # lib/generators/apache_age/node/entity_generator.rb
1
2
  require 'rails/generators'
2
3
  require 'rails/generators/named_base'
3
4
 
5
+ require_relative '../generator_entity_helpers'
6
+
4
7
  module ApacheAge
5
8
  class NodeGenerator < Rails::Generators::NamedBase
9
+ include ApacheAge::GeneratorEntityHelpers
10
+
11
+ desc "Generates node (model) with attributes."
12
+
6
13
  source_root File.expand_path('templates', __dir__)
7
14
  argument :attributes, type: :array, default: [], banner: "field:type field:type"
8
15
 
9
16
  def perform_task
10
- behavior == :invoke ? create_node_file : destroy_node_file
11
- end
12
-
13
- private
14
-
15
- def create_node_file
16
- template "node.rb.tt", File.join(destination_root, "app/nodes", class_path, "#{file_name}.rb")
17
- add_type_config
18
- end
19
-
20
- def destroy_node_file
21
- file_path = File.join(destination_root, "app/nodes", class_path, "#{file_name}.rb")
22
- File.delete(file_path) if File.exist?(file_path)
23
- remove_type_config
24
- end
25
-
26
- def attributes_list
27
- attributes.map { |attr| { name: attr.name, type: attr.type } }
28
- end
29
-
30
- def unique_attributes
31
- attributes_list.map { |attr| attr[:name].to_sym }
32
- end
33
-
34
- def parent_module
35
- class_path.map(&:camelize).join('::')
36
- end
37
-
38
- def full_class_name
39
- parent_module.empty? ? class_name : "#{parent_module}::#{class_name}"
40
- end
41
-
42
- def indented_namespace
43
- return '' if parent_module.empty?
44
-
45
- parent_module.split('::').map.with_index do |namespace, index|
46
- "#{' ' * index}module #{namespace}"
47
- end.join("\n") + "\n"
48
- end
49
-
50
- def indented_end_namespace
51
- return '' if parent_module.empty?
52
-
53
- parent_module.split('::').map.with_index do |_, index|
54
- "#{' ' * (parent_module.split('::').length - 1 - index)}end"
55
- end.join("\n") + "\n"
56
- end
57
-
58
- def add_type_config
59
- return unless File.exist?(types_config_file)
60
-
61
- types_content = File.read(types_config_file)
62
- types_content.sub!(/^end\s*$/, "#{new_type_content}end")
63
- File.open(types_config_file, 'w') { |file| file.write(types_content) }
64
- puts " modified: config/initializers/types.rb"
65
- end
66
-
67
- def remove_type_config
68
- return unless File.exist?(types_config_file)
69
-
70
- type_to_remove = new_type_content
71
-
72
- types_content = File.read(types_config_file)
73
- types_content.gsub!(type_to_remove, '')
74
- File.open(types_config_file, 'w') { |file| file.write(types_content) }
75
- end
76
-
77
- def types_config_file = File.join(Rails.root, 'config/initializers/types.rb')
78
-
79
- def new_type_content
80
- file_path = [class_path, file_name].reject(&:blank?).join('/').downcase
81
- node_namespace = class_path.map(&:capitalize).join('::')
82
- node_class_name = file_name.split('_').map(&:capitalize).join
83
- node_namespaced_class = [node_namespace, node_class_name].reject(&:blank?).join('::')
84
- type_name = [class_path.join('_'), file_name].reject(&:blank?).join('_')
85
- content =
86
- <<-RUBY
87
- require_dependency '#{file_path}'
88
- ActiveModel::Type.register(
89
- :#{type_name}, ApacheAge::Types::AgeTypeGenerator.create_type_for(#{node_namespaced_class})
90
- )
91
- RUBY
17
+ age_type = 'node'
18
+ behavior == :invoke ? generate_age_entity(age_type) : destroy_age_entity(age_type)
92
19
  end
93
20
  end
94
21
  end
@@ -9,9 +9,9 @@ class <%= class_name %>
9
9
  validates :<%= attribute[:name] %>, presence: true
10
10
  <%- end -%>
11
11
 
12
- # unique node validator (remove any attributes that are not important to uniqueness)
12
+ # custom unique node validator (remove any attributes that are NOT important to uniqueness)
13
13
  validates_with(
14
- ApacheAge::Validators::UniqueVertexValidator,
14
+ ApacheAge::Validators::UniqueVertex,
15
15
  attributes: <%= unique_attributes.inspect %>
16
16
  )
17
17
  end
@@ -0,0 +1,16 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ bin/rails generate apache_age:scaffold_node Pet name birthdate:date
6
+
7
+ This will create:
8
+ create app/nodes/pet.rb
9
+ modified: config/initializers/types.rb
10
+ create app/controllers/pets_controller.rb
11
+ route resources :pets
12
+ create app/views/pets/index.html.erb
13
+ create app/views/pets/edit.html.erb
14
+ create app/views/pets/show.html.erb
15
+ create app/views/pets/new.html.erb
16
+ create app/views/pets/partial.html.erb
@@ -0,0 +1,68 @@
1
+ # lib/generators/apache_age/scaffold_node/scaffold_node_generator.rb
2
+
3
+ require 'rails/generators'
4
+ require 'rails/generators/named_base'
5
+ require 'rails/generators/resource_helpers'
6
+
7
+ require_relative '../generator_entity_helpers'
8
+ require_relative '../generator_resource_helpers'
9
+
10
+ module ApacheAge
11
+ class ScaffoldNodeGenerator < Rails::Generators::NamedBase
12
+ include Rails::Generators::ResourceHelpers
13
+ # include ApacheAge::GeneratorEntityHelpers
14
+ # include ApacheAge::GeneratorResourceHelpers
15
+
16
+ desc "Generates a node, and its controller and views with the given attributes."
17
+
18
+ source_root File.expand_path("templates", __dir__)
19
+
20
+ argument :attributes, type: :array, default: [], banner: "field:type field:type"
21
+
22
+ def create_model_file
23
+ invoke 'apache_age:node', [name] + attributes.collect { |attr| "#{attr.name}:#{attr.type}" }
24
+ end
25
+
26
+ def create_controller_files
27
+ template(
28
+ "node_controller.rb.tt",
29
+ File.join("app/controllers", controller_class_path, "#{controller_file_name}_controller.rb")
30
+ )
31
+ end
32
+
33
+ def create_route
34
+ if class_path.empty?
35
+ route "resources :#{file_name.pluralize}"
36
+ else
37
+ route nested_route(class_path, file_name)
38
+ end
39
+ end
40
+
41
+ def copy_view_files
42
+ available_views.each do |view|
43
+ view_name = view == 'partial' ? "_#{singular_table_name}" : view
44
+ filename = filename_with_extensions(view_name)
45
+ template "views/#{view}.html.erb.tt", File.join("app/views", controller_file_path, filename)
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def available_views
52
+ %w[index edit show new partial _form]
53
+ end
54
+
55
+ def filename_with_extensions(view)
56
+ [view, :html, :erb].compact.join('.')
57
+ end
58
+
59
+ def nested_route(class_path, file_name)
60
+ # "namespace :#{class_path.join(':')} do\n resources :#{file_name.pluralize}\nend"
61
+ <<~RUBY
62
+ namespace :#{class_path.join(':')} do
63
+ resources :#{file_name.pluralize}
64
+ end
65
+ RUBY
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,50 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+ before_action :set_<%= singular_table_name %>, only: %i[show edit update destroy]
3
+
4
+ def index
5
+ @<%= plural_table_name %> = <%= class_name %>.all
6
+ end
7
+
8
+ def show
9
+ end
10
+
11
+ def new
12
+ @<%= singular_table_name %> = <%= class_name %>.new
13
+ end
14
+
15
+ def edit
16
+ end
17
+
18
+ def create
19
+ @<%= singular_table_name %> = <%= class_name %>.new(<%= singular_table_name %>_params)
20
+
21
+ if @<%= singular_table_name %>.save
22
+ redirect_to @<%= singular_table_name %>, notice: '<%= human_name %> was successfully created.'
23
+ else
24
+ render :new
25
+ end
26
+ end
27
+
28
+ def update
29
+ if @<%= singular_table_name %>.update(<%= singular_table_name %>_params)
30
+ redirect_to @<%= singular_table_name %>, notice: '<%= human_name %> was successfully updated.'
31
+ else
32
+ render :edit
33
+ end
34
+ end
35
+
36
+ def destroy
37
+ @<%= singular_table_name %>.destroy
38
+ redirect_to <%= index_helper %>_url, notice: '<%= human_name %> was successfully destroyed.'
39
+ end
40
+
41
+ private
42
+
43
+ def set_<%= singular_table_name %>
44
+ @<%= singular_table_name %> = <%= class_name %>.find(params[:id])
45
+ end
46
+
47
+ def <%= singular_table_name %>_params
48
+ params.require(:<%= singular_table_name %>).permit(<%= attributes.map { |attr| ":#{attr.name}" }.join(', ') %>)
49
+ end
50
+ end
@@ -0,0 +1,37 @@
1
+ <%%= form_with(model: <%= model_resource_name %>) do |form| %>
2
+ <%% if <%= singular_table_name %>.errors.any? %>
3
+ <div style="color: red">
4
+ <h2><%%= pluralize(<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</h2>
5
+
6
+ <ul>
7
+ <%% <%= singular_table_name %>.errors.each do |error| %>
8
+ <li><%%= error.full_message %></li>
9
+ <%% end %>
10
+ </ul>
11
+ </div>
12
+ <%% end %>
13
+
14
+ <% attributes.each do |attribute| -%>
15
+ <div>
16
+ <% if attribute.password_digest? -%>
17
+ <%%= form.label :password, style: "display: block" %>
18
+ <%%= form.password_field :password %>
19
+ </div>
20
+
21
+ <div>
22
+ <%%= form.label :password_confirmation, style: "display: block" %>
23
+ <%%= form.password_field :password_confirmation %>
24
+ <% elsif attribute.attachments? -%>
25
+ <%%= form.label :<%= attribute.column_name %>, style: "display: block" %>
26
+ <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, multiple: true %>
27
+ <% else -%>
28
+ <%%= form.label :<%= attribute.column_name %>, style: "display: block" %>
29
+ <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %> %>
30
+ <% end -%>
31
+ </div>
32
+
33
+ <% end -%>
34
+ <div>
35
+ <%%= form.submit %>
36
+ </div>
37
+ <%% end %>
@@ -0,0 +1,37 @@
1
+ <%%= form_with(model: <%= model_resource_name %>) do |form| %>
2
+ <%% if <%= singular_table_name %>.errors.any? %>
3
+ <div style="color: red">
4
+ <h2><%%= pluralize(<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</h2>
5
+
6
+ <ul>
7
+ <%% <%= singular_table_name %>.errors.each do |error| %>
8
+ <li><%%= error.full_message %></li>
9
+ <%% end %>
10
+ </ul>
11
+ </div>
12
+ <%% end %>
13
+
14
+ <% attributes.each do |attribute| -%>
15
+ <div>
16
+ <% if attribute.password_digest? -%>
17
+ <%%= form.label :password, style: "display: block" %>
18
+ <%%= form.password_field :password %>
19
+ </div>
20
+
21
+ <div>
22
+ <%%= form.label :password_confirmation, style: "display: block" %>
23
+ <%%= form.password_field :password_confirmation %>
24
+ <% elsif attribute.attachments? -%>
25
+ <%%= form.label :<%= attribute.column_name %>, style: "display: block" %>
26
+ <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, multiple: true %>
27
+ <% else -%>
28
+ <%%= form.label :<%= attribute.column_name %>, style: "display: block" %>
29
+ <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %> %>
30
+ <% end -%>
31
+ </div>
32
+
33
+ <% end -%>
34
+ <div>
35
+ <%%= form.submit %>
36
+ </div>
37
+ <%% end %>
@@ -0,0 +1,12 @@
1
+ <%% content_for :title, "Editing <%= human_name.downcase %>" %>
2
+
3
+ <h1>Editing <%= human_name.downcase %></h1>
4
+
5
+ <%%= render "form", <%= singular_table_name %>: @<%= singular_table_name %> %>
6
+
7
+ <br>
8
+
9
+ <div>
10
+ <%%= link_to "Show this <%= human_name.downcase %>", <%= model_resource_name(prefix: "@") %> %> |
11
+ <%%= link_to "Back to <%= human_name.pluralize.downcase %>", <%= index_helper(type: :path) %> %>
12
+ </div>
@@ -0,0 +1,12 @@
1
+ <%% content_for :title, "Editing <%= human_name.downcase %>" %>
2
+
3
+ <h1>Editing <%= human_name.downcase %></h1>
4
+
5
+ <%%= render "form", <%= singular_table_name %>: @<%= singular_table_name %> %>
6
+
7
+ <br>
8
+
9
+ <div>
10
+ <%%= link_to "Show this <%= human_name.downcase %>", <%= model_resource_name(prefix: "@") %> %> |
11
+ <%%= link_to "Back to <%= human_name.pluralize.downcase %>", <%= index_helper(type: :path) %> %>
12
+ </div>
@@ -0,0 +1,16 @@
1
+ <p style="color: green"><%%= notice %></p>
2
+
3
+ <%% content_for :title, "<%= human_name.pluralize %>" %>
4
+
5
+ <h1><%= human_name.pluralize %></h1>
6
+
7
+ <div id="<%= plural_table_name %>">
8
+ <%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %>
9
+ <%%= render <%= singular_table_name %> %>
10
+ <p>
11
+ <%%= link_to "Show this <%= human_name.downcase %>", <%= model_resource_name(singular_table_name) %> %>
12
+ </p>
13
+ <%% end %>
14
+ </div>
15
+
16
+ <%%= link_to "New <%= human_name.downcase %>", <%= new_helper(type: :path) %> %>
@@ -0,0 +1,16 @@
1
+ <p style="color: green"><%%= notice %></p>
2
+
3
+ <%% content_for :title, "<%= human_name.pluralize %>" %>
4
+
5
+ <h1><%= human_name.pluralize %></h1>
6
+
7
+ <div id="<%= plural_table_name %>">
8
+ <%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %>
9
+ <%%= render '<%= singular_table_name %>', <%= singular_table_name %>: <%= singular_table_name %> %>
10
+ <p>
11
+ <%%= link_to "Show this <%= human_name.downcase %>", <%= model_resource_name(singular_table_name) %> %>
12
+ </p>
13
+ <%% end %>
14
+ </div>
15
+
16
+ <%%= link_to "New <%= human_name.downcase %>", <%= new_helper(type: :path) %> %>
@@ -0,0 +1,11 @@
1
+ <%% content_for :title, "New <%= human_name.downcase %>" %>
2
+
3
+ <h1>New <%= human_name.downcase %></h1>
4
+
5
+ <%%= render "form", <%= singular_table_name %>: @<%= singular_table_name %> %>
6
+
7
+ <br>
8
+
9
+ <div>
10
+ <%%= link_to "Back to <%= human_name.pluralize.downcase %>", <%= index_helper(type: :path) %> %>
11
+ </div>
@@ -0,0 +1,11 @@
1
+ <%% content_for :title, "New <%= human_name.downcase %>" %>
2
+
3
+ <h1>New <%= human_name.downcase %></h1>
4
+
5
+ <%%= render "form", <%= singular_table_name %>: @<%= singular_table_name %> %>
6
+
7
+ <br>
8
+
9
+ <div>
10
+ <%%= link_to "Back to <%= human_name.pluralize.downcase %>", <%= index_helper(type: :path) %> %>
11
+ </div>
@@ -0,0 +1,17 @@
1
+ <div id="<%%= dom_id <%= singular_table_name %> %>">
2
+ <% attributes.reject(&:password_digest?).each do |attribute| -%>
3
+ <p>
4
+ <strong><%= attribute.human_name %>:</strong>
5
+ <% if attribute.attachment? -%>
6
+ <%%= link_to <%= singular_table_name %>.<%= attribute.column_name %>.filename, <%= singular_table_name %>.<%= attribute.column_name %> if <%= singular_table_name %>.<%= attribute.column_name %>.attached? %>
7
+ <% elsif attribute.attachments? -%>
8
+ <%% <%= singular_table_name %>.<%= attribute.column_name %>.each do |<%= attribute.singular_table_name %>| %>
9
+ <div><%%= link_to <%= attribute.singular_table_name %>.filename, <%= attribute.singular_table_name %> %></div>
10
+ <%% end %>
11
+ <% else -%>
12
+ <%%= <%= singular_table_name %>.<%= attribute.column_name %> %>
13
+ <% end -%>
14
+ </p>
15
+
16
+ <% end -%>
17
+ </div>
@@ -0,0 +1,17 @@
1
+ <div id="<%%= dom_id <%= singular_table_name %> %>">
2
+ <% attributes.reject(&:password_digest?).each do |attribute| -%>
3
+ <p>
4
+ <strong><%= attribute.human_name %>:</strong>
5
+ <% if attribute.attachment? -%>
6
+ <%%= link_to <%= singular_table_name %>.<%= attribute.column_name %>.filename, <%= singular_table_name %>.<%= attribute.column_name %> if <%= singular_table_name %>.<%= attribute.column_name %>.attached? %>
7
+ <% elsif attribute.attachments? -%>
8
+ <%% <%= singular_table_name %>.<%= attribute.column_name %>.each do |<%= attribute.singular_name %>| %>
9
+ <div><%%= link_to <%= attribute.singular_name %>.filename, <%= attribute.singular_name %> %></div>
10
+ <%% end %>
11
+ <% else -%>
12
+ <%%= <%= singular_table_name %>.<%= attribute.column_name %> %>
13
+ <% end -%>
14
+ </p>
15
+
16
+ <% end -%>
17
+ </div>
@@ -0,0 +1,10 @@
1
+ <p style="color: green"><%%= notice %></p>
2
+
3
+ <%%= render @<%= singular_table_name %> %>
4
+
5
+ <div>
6
+ <%%= link_to "Edit this <%= human_name.downcase %>", <%= edit_helper(type: :path) %> %> |
7
+ <%%= link_to "Back to <%= human_name.pluralize.downcase %>", <%= index_helper(type: :path) %> %>
8
+
9
+ <%%= button_to "Destroy this <%= human_name.downcase %>", <%= model_resource_name(prefix: "@") %>, method: :delete %>
10
+ </div>
@@ -0,0 +1,10 @@
1
+ <p style="color: green"><%%= notice %></p>
2
+
3
+ <%%= render '<%= singular_table_name %>', <%= singular_table_name %>: @<%= singular_table_name %> %>
4
+
5
+ <div>
6
+ <%%= link_to "Edit this <%= human_name.downcase %>", <%= edit_helper(type: :path) %> %> |
7
+ <%%= link_to "Back to <%= human_name.pluralize.downcase %>", <%= index_helper(type: :path) %> %>
8
+
9
+ <%%= button_to "Destroy this <%= human_name.downcase %>", <%= model_resource_name(prefix: "@") %>, method: :delete %>
10
+ </div>
@@ -1,3 +1,3 @@
1
1
  module RailsAge
2
- VERSION = '0.4.1'
2
+ VERSION = '0.5.2'
3
3
  end
data/lib/rails_age.rb CHANGED
@@ -11,7 +11,7 @@ module ApacheAge
11
11
  require 'apache_age/entities/edge'
12
12
  require 'apache_age/entities/entity'
13
13
  require 'apache_age/entities/vertex'
14
+ require 'apache_age/validators/unique_edge'
15
+ require 'apache_age/validators/unique_vertex'
14
16
  require 'apache_age/types/age_type_generator'
15
- require 'apache_age/validators/unique_edge_validator'
16
- require 'apache_age/validators/unique_vertex_validator'
17
17
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_age
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bill Tihen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-15 00:00:00.000000000 Z
11
+ date: 2024-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -73,15 +73,32 @@ files:
73
73
  - lib/apache_age/entities/entity.rb
74
74
  - lib/apache_age/entities/vertex.rb
75
75
  - lib/apache_age/types/age_type_generator.rb
76
- - lib/apache_age/validators/unique_edge_validator.rb
77
- - lib/apache_age/validators/unique_vertex_validator.rb
76
+ - lib/apache_age/validators/unique_edge.rb
77
+ - lib/apache_age/validators/unique_vertex.rb
78
78
  - lib/apache_age/validators/vertex_type_validator.rb
79
79
  - lib/generators/apache_age/edge/USAGE
80
80
  - lib/generators/apache_age/edge/edge_generator.rb
81
81
  - lib/generators/apache_age/edge/templates/edge.rb.tt
82
+ - lib/generators/apache_age/generator_entity_helpers.rb
83
+ - lib/generators/apache_age/generator_resource_helpers.rb
82
84
  - lib/generators/apache_age/node/USAGE
83
85
  - lib/generators/apache_age/node/node_generator.rb
84
86
  - lib/generators/apache_age/node/templates/node.rb.tt
87
+ - lib/generators/apache_age/scaffold_node/USAGE
88
+ - lib/generators/apache_age/scaffold_node/scaffold_node_generator.rb
89
+ - lib/generators/apache_age/scaffold_node/templates/node_controller.rb.tt
90
+ - lib/generators/apache_age/scaffold_node/templates/views/_form.html.erb copy.tt
91
+ - lib/generators/apache_age/scaffold_node/templates/views/_form.html.erb.tt
92
+ - lib/generators/apache_age/scaffold_node/templates/views/edit.html.erb copy.tt
93
+ - lib/generators/apache_age/scaffold_node/templates/views/edit.html.erb.tt
94
+ - lib/generators/apache_age/scaffold_node/templates/views/index.html.erb copy.tt
95
+ - lib/generators/apache_age/scaffold_node/templates/views/index.html.erb.tt
96
+ - lib/generators/apache_age/scaffold_node/templates/views/new.html.erb copy.tt
97
+ - lib/generators/apache_age/scaffold_node/templates/views/new.html.erb.tt
98
+ - lib/generators/apache_age/scaffold_node/templates/views/partial.html.erb copy.tt
99
+ - lib/generators/apache_age/scaffold_node/templates/views/partial.html.erb.tt
100
+ - lib/generators/apache_age/scaffold_node/templates/views/show.html.erb copy.tt
101
+ - lib/generators/apache_age/scaffold_node/templates/views/show.html.erb.tt
85
102
  - lib/rails_age.rb
86
103
  - lib/rails_age/engine.rb
87
104
  - lib/rails_age/version.rb