ead 0.4.4 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 521bf231cf8fd799589f9a95abb7c12d30fab37ea1cc4829b81f2f516a49ed0f
4
- data.tar.gz: e855abd1586c963eaf182e89f4fac8af6f7a4ef30dccc5b692afea3261320173
3
+ metadata.gz: 92794b354827c99861ef67bada7a6b903982f728f83ef61825e84aa774f3b7a5
4
+ data.tar.gz: f1ee6af6f98952cc264ced02309681e15085ea04bc13e27d0de3a213aa6531f9
5
5
  SHA512:
6
- metadata.gz: 02530f8d06d43e5e55b10acb4d92a2ff3b9931aabc45f468805b798366f35dd87a60722c9b5e8d788e3862b53196a4b747bdb8d90b8396e7c89fb9cdcf05c4a5
7
- data.tar.gz: b37b8c574101446d2bdb997d80c67d4da0ffa9aef271f6ef26ea7e34550000138d8105f88051a623793c4c158fd6a21e87f27572b685fdac4cc5c4a6f57b2ca8
6
+ metadata.gz: 5c6ff6ee9db8731482c286bdf0c00a64e39cfcb8a628a3a78f56fb4187fed8551288c907d0539af2c6a87f6534be044bc283f7e0dc7e6e28b70669d21e5badfb
7
+ data.tar.gz: e9deeae107a89272452f2a3863b1deb99dfe2658f64ce6e364656d6067d11f8b4a034d250cc6b2e80a7fbf41eaf59aa3223e8c90c5d893e8206fbec61446a748
data/lib/association.rb CHANGED
@@ -48,6 +48,8 @@ class Association
48
48
  end
49
49
 
50
50
  def set_middle_entity
51
+ return unless through?
52
+
51
53
  source = first_entity
52
54
  target = second_entity
53
55
 
@@ -72,8 +74,8 @@ class Association
72
74
  target.children_has_one +
73
75
  target.children_has_one_through
74
76
  ).include?(through_entity) || (
75
- through_entity.parents_has_many.map(&:clone_parent).include?(target.clone_parent) ||
76
- through_entity.parents_has_one.map(&:clone_parent).include?(target.clone_parent)
77
+ through_entity.parents_has_many.map(&:table).include?(target.table) ||
78
+ through_entity.parents_has_one.map(&:table).include?(target.table)
77
79
  )
78
80
  )
79
81
 
@@ -103,10 +105,8 @@ class Association
103
105
  end
104
106
  end
105
107
 
106
- def self.set_middle_entities
107
- associations = all.select(&:through?)
108
-
109
- associations.each(&:set_middle_entity)
108
+ def update_model_from_entity
109
+ first_entity.update_model(second_entity, self)
110
110
  end
111
111
 
112
112
  def has_many?
data/lib/ead.rb CHANGED
@@ -7,11 +7,11 @@ class EAD
7
7
  def import_JSON(user_arguments)
8
8
  file = File.read(user_arguments[0] || './EAD.json')
9
9
 
10
- unless ['0.4.0', '0.4.1', '0.4.2', '0.4.2', '0.4.3', '0.4.4'].include? JSON.parse(file)['version']
10
+ unless ['0.4.0', '0.4.1', '0.4.2', '0.4.3', '0.4.4', '0.4.5', '0.4.6'].include? JSON.parse(file)['version']
11
11
  puts "\n\n----------------"
12
12
  puts "\e[31m#{
13
- 'Versions of your EAD file and the gem are not compatible.'\
14
- ' So, you may have some unexpected results.'\
13
+ 'Versions of your EAD file and the gem are not compatible. '\
14
+ 'So, you may have some unexpected results.'\
15
15
  'To run your EAD file correctly, please run'
16
16
  }\e[0m"
17
17
 
@@ -27,49 +27,47 @@ class EAD
27
27
  end
28
28
 
29
29
  def create_objects(file)
30
- @nodes = JSON.parse(file)['nodes']
31
- @edges = JSON.parse(file)['edges']
32
- @tables = JSON.parse(file)['tables']
30
+ parsed_file = JSON.parse(file)
33
31
 
34
- @tables = @tables.map do |(id)|
35
- Table.new(id, @tables)
32
+ parsed_tables = parsed_file['tables']
33
+ parsed_nodes = parsed_file['nodes']
34
+ parsed_edges = parsed_file['edges']
35
+
36
+ @tables = parsed_tables.map do |id, parsed_table|
37
+ Table.new(id, parsed_table)
36
38
  end
37
39
 
38
- @nodes.map! do |node|
40
+ Table.update_superclasses(parsed_tables)
41
+
42
+ @nodes = parsed_nodes.map do |node|
39
43
  Entity.new(node)
40
44
  end
41
45
 
42
- @edges.map! do |edge|
46
+ @edges = parsed_edges.map do |edge|
43
47
  Association.new(edge)
44
48
  end
45
49
  end
46
50
 
47
- def check_implement_objects(file)
48
- create_objects(file)
49
-
50
- Entity.all.each do |entity|
51
- entity.clone_parent.entities << entity
52
- end
53
-
51
+ def check_implement_objects
54
52
  Table.all.each(&:create_model)
55
53
 
54
+ Table.all.each(&:add_polymorphic_reference_migration_for_sti)
55
+
56
56
  Table.all.each(&:add_reference_migration)
57
57
 
58
- Association.set_middle_entities
58
+ Association.all.each(&:set_middle_entity)
59
59
 
60
- Association.all.each do |association|
61
- association.first_entity.update_model(association.second_entity, association)
62
- end
60
+ Association.all.each(&:update_model_from_entity)
63
61
  end
64
62
 
65
63
  def check_latest_version
66
64
  response = JSON.parse RestClient.get 'https://api.github.com/repos/ozovalihasan/ead/tags'
67
65
 
68
- unless response.first['name'] == 'v0.4.4'
66
+ unless response.first['name'] == 'v0.4.6'
69
67
  puts "\n\n----------------"
70
68
  puts "\n\e[33m#{
71
- 'A new version of this gem has been released.'\
72
- ' Please check it. https://github.com/ozovalihasan/ead-g/releases'
69
+ 'A new version of this gem has been released. '\
70
+ 'Please check it. https://github.com/ozovalihasan/ead-g/releases'
73
71
  }\e[0m"
74
72
 
75
73
  puts "\n----------------\n\n"
@@ -77,8 +75,8 @@ class EAD
77
75
  rescue StandardError
78
76
  puts "\n\n----------------"
79
77
  puts "\n\e[31m#{
80
- 'If you want to check the latest version of this gem,'\
81
- ' you need to have a stable internet connection.'
78
+ 'If you want to check the latest version of this gem, '\
79
+ 'you need to have a stable internet connection.'
82
80
  }\e[0m"
83
81
 
84
82
  puts "\n----------------\n\n"
@@ -87,6 +85,7 @@ class EAD
87
85
  def start(user_arguments)
88
86
  check_latest_version
89
87
  file = import_JSON(user_arguments)
90
- check_implement_objects(file)
88
+ create_objects(file)
89
+ check_implement_objects
91
90
  end
92
91
  end
data/lib/entity.rb CHANGED
@@ -3,15 +3,15 @@ require 'association'
3
3
  require 'project_file'
4
4
 
5
5
  class Entity < TableEntityBase
6
- attr_accessor(:name, :id, :twin_name, :clone_parent, :parent, :parent_association, :associations, :parent_associations,
6
+ attr_accessor(:name, :id, :table, :parent, :parent_association, :associations, :parent_associations,
7
7
  :parents_has_one, :parents_has_many, :parents_through, :children_has_one, :children_has_many, :children_through,
8
8
  :children_has_one_through, :children_has_many_through, :parents_has_one_through, :parents_has_many_through)
9
9
 
10
10
  def initialize(node)
11
11
  @id = node['id']
12
- @name = node['data']['name'].split(' || ')[0].underscore.singularize
13
- @twin_name = node['data']['name'].split(' || ')[1]&.underscore&.singularize
14
- @clone_parent = Table.find(node['data']['tableId'])
12
+ @name = node['data']['name'].underscore.singularize
13
+ @table = Table.find(node['data']['tableId'])
14
+ @table.entities << self
15
15
 
16
16
  @parent_associations = []
17
17
  @associations = []
@@ -29,61 +29,106 @@ class Entity < TableEntityBase
29
29
  @children_through = []
30
30
  end
31
31
 
32
+ def self.find_by_name(name)
33
+ all.find { |entity| entity.name == name }
34
+ end
35
+
32
36
  def model_name
33
- clone_parent.name.camelize
37
+ table.name.camelize
34
38
  end
35
39
 
36
- def tables_same?(entity)
37
- table == entity.table
40
+ def root_classes_same?(entity)
41
+ table.root_class == entity.table.root_class
38
42
  end
39
43
 
40
- def self.find_by_name(name)
41
- all.find { |entity| entity.name == name }
44
+ def table_name_different?
45
+ table.name != name
42
46
  end
43
47
 
44
- def clone_name_different?
45
- clone_parent.name != name
48
+ def root_class_name_different?
49
+ table.root_class.name != name
46
50
  end
47
51
 
48
52
  def one_polymorphic_names?(entity)
49
53
  table.polymorphic && table.polymorphic_names.include?(entity.name)
50
54
  end
51
55
 
52
- def table
53
- clone_parent
54
- end
55
-
56
56
  def update_end_model_migration_files(start_entity, association)
57
- polymorphic_end = one_polymorphic_names?(start_entity)
58
-
59
- return if polymorphic_end
57
+ return unless association.has_any?
60
58
 
61
59
  end_model_line = {}
62
60
  end_migration_line = {}
63
61
 
64
- if association.has_any?
65
- end_model_line['belongs_to'] = ":#{start_entity.name}"
62
+ end_model_line['belongs_to'] = ":#{start_entity.name}"
63
+
64
+ if root_classes_same?(start_entity)
65
+ end_model_line['optional'] = 'true'
66
+ end_migration_line['null'] = 'true'
67
+ else
68
+ end_migration_line['null'] = 'false'
69
+ end
70
+
71
+ end_migration_line['null'] = 'true' unless table.root_class?
72
+
73
+ polymorphic_end = one_polymorphic_names?(start_entity)
74
+
75
+ unless polymorphic_end
76
+ end_model_line['class_name'] = "\"#{start_entity.table.name.camelize}\"" if start_entity.table_name_different?
66
77
 
67
- if tables_same?(start_entity)
68
- end_model_line['optional'] = 'true'
69
- end_migration_line['null'] = 'true'
70
- else
71
- end_migration_line['null'] = 'false'
78
+ if start_entity.root_class_name_different?
79
+ end_migration_line['foreign_key'] = "{ to_table: :#{start_entity.table.root_class.name.pluralize} }"
72
80
  end
73
81
 
74
- if !polymorphic_end && start_entity.clone_name_different?
75
- end_model_line['class_name'] = "\"#{start_entity.clone_parent.name.camelize}\""
76
- end_migration_line['foreign_key'] = "{ to_table: :#{start_entity.clone_parent.name.pluralize} }"
82
+ if start_entity.table.superclass && start_entity.root_class_name_different?
83
+ end_migration_line['column'] = ":#{start_entity.name}_id"
77
84
  end
85
+
86
+ end
87
+
88
+ update_project_files(start_entity, end_model_line, end_migration_line)
89
+ end
90
+
91
+ def update_project_files(start_entity, end_model_line, end_migration_line)
92
+ update_model_files(start_entity, end_model_line)
93
+ update_migration_files(start_entity, end_migration_line)
94
+ end
95
+
96
+ def update_model_files(start_entity, end_model_line)
97
+ return if end_model_line.empty?
98
+
99
+ polymorphic_end = one_polymorphic_names?(start_entity)
100
+
101
+ if polymorphic_end
102
+ ProjectFile.update_line(table.name, 'model', /belongs_to :#{start_entity.name}/, end_model_line)
103
+ else
104
+ ProjectFile.add_belong_line(table.name, end_model_line)
78
105
  end
106
+ end
79
107
 
80
- ProjectFile.add_belong_line(clone_parent.name, end_model_line) unless end_model_line.empty?
108
+ def update_migration_files(start_entity, end_migration_line)
109
+ return if end_migration_line.empty?
81
110
 
82
- unless end_migration_line.empty?
83
- migration_name = "Add#{start_entity.name.camelize}RefTo#{clone_parent.name.camelize}".underscore
111
+ polymorphic_end = one_polymorphic_names?(start_entity)
84
112
 
85
- ProjectFile.update_line(migration_name, 'reference_migration', /add_reference :#{clone_parent.name.pluralize}/,
86
- end_migration_line)
113
+ if table.root_class? && polymorphic_end
114
+ migration_name = "Create#{table.name.camelize.pluralize}".underscore
115
+
116
+ ProjectFile.update_line(
117
+ migration_name,
118
+ 'migration',
119
+ /t.references :#{start_entity.name}/,
120
+ end_migration_line
121
+ )
122
+
123
+ else
124
+ migration_name = "Add#{start_entity.name.camelize}RefTo#{table.root_class.name.camelize}".underscore
125
+
126
+ ProjectFile.update_line(
127
+ migration_name,
128
+ 'reference_migration',
129
+ /add_reference :#{table.root_class.name.pluralize}/,
130
+ end_migration_line
131
+ )
87
132
  end
88
133
  end
89
134
 
@@ -103,7 +148,7 @@ class Entity < TableEntityBase
103
148
  line_content = {}
104
149
 
105
150
  if association.has_many? || (children_has_many_through.include? end_entity)
106
- line_content['has_many'] = if intermediate_entity&.one_polymorphic_names?(end_entity) && (association.has_many? || (children_has_many_through.include? end_entity))
151
+ line_content['has_many'] = if intermediate_entity&.one_polymorphic_names?(end_entity) && (children_has_many_through.include? end_entity)
107
152
  ":#{end_entity.table.name.pluralize}"
108
153
  else
109
154
  ":#{end_model}"
@@ -111,7 +156,7 @@ class Entity < TableEntityBase
111
156
  end
112
157
 
113
158
  if association.has_one? || (children_has_one_through.include? end_entity)
114
- line_content['has_one'] = if intermediate_entity&.one_polymorphic_names?(end_entity) && (association.has_one? || (children_has_one_through.include? end_entity))
159
+ line_content['has_one'] = if intermediate_entity&.one_polymorphic_names?(end_entity) && (children_has_one_through.include? end_entity)
115
160
  ":#{end_entity.table.name}"
116
161
  else
117
162
  ":#{end_model}"
@@ -125,11 +170,11 @@ class Entity < TableEntityBase
125
170
  line_content['source_type'] = "\"#{end_entity.table.name.camelize}\" "
126
171
  end
127
172
  elsif !intermediate_entity
128
- line_content['class_name'] = "\"#{end_entity.table.name.camelize}\"" if end_entity.clone_name_different?
173
+ line_content['class_name'] = "\"#{end_entity.table.name.camelize}\"" if end_entity.table_name_different?
129
174
 
130
175
  if end_entity.one_polymorphic_names?(self)
131
176
  line_content['as'] = ":#{name}"
132
- elsif clone_name_different?
177
+ elsif table_name_different?
133
178
  line_content['foreign_key'] = "\"#{name.singularize}_id\""
134
179
  end
135
180
  end
data/lib/project_file.rb CHANGED
@@ -3,15 +3,15 @@ require 'fileutils'
3
3
  class ProjectFile
4
4
  def self.open_close(name, type, &block)
5
5
  case type
6
- when 'migration'
7
- tempfile_name = './db/migrate/migration_update.rb'
8
- file_name = Dir.glob("./db/migrate/*_#{name.pluralize}.rb").first
9
6
  when 'model'
10
7
  tempfile_name = './app/models/model_update.rb'
11
8
  file_name = "./app/models/#{name}.rb"
12
- when 'reference_migration'
9
+ when 'migration'
13
10
  tempfile_name = './db/migrate/migration_update.rb'
14
11
  file_name = Dir.glob("./db/migrate/*_#{name}.rb").first
12
+ when 'reference_migration'
13
+ tempfile_name = './db/migrate/reference_migration_update.rb'
14
+ file_name = Dir.glob("./db/migrate/*_#{name}.rb").first
15
15
  end
16
16
  tempfile = File.open(tempfile_name, 'w')
17
17
  file = File.new(file_name)
@@ -34,7 +34,7 @@ class ProjectFile
34
34
  line.gsub!(/ *\n/, '')
35
35
  line_content.each do |key, value|
36
36
  if line.include? key
37
- line.gsub!(/#{key}: [^(\s,)]*/, "#{key}: #{value}#{Regexp.last_match(1)}")
37
+ line.gsub!(/#{key}: [^(,)]*/, "#{key}: #{value}")
38
38
  else
39
39
  line << ", #{key}: #{value}"
40
40
  end
data/lib/table.rb CHANGED
@@ -4,36 +4,74 @@ require 'association'
4
4
  require 'active_support/core_ext/string'
5
5
 
6
6
  class Table < TableEntityBase
7
- attr_accessor :name, :id, :twin_name, :attributes, :entities, :polymorphic, :polymorphic_names
7
+ attr_accessor :name, :id, :attributes, :entities, :polymorphic, :polymorphic_names, :superclass, :subclasses
8
8
 
9
- def initialize(table_id, tables)
9
+ def initialize(table_id, table)
10
10
  @id = table_id
11
- @name = tables[table_id]['name'].split(' || ')[0].underscore.singularize
11
+ @name = table['name'].underscore.singularize
12
12
  @entities = []
13
13
  @polymorphic = false
14
14
  @polymorphic_names = []
15
15
  @attributes = []
16
- tables[table_id]['attributes'].each do |(_attribute_id, attribute)|
16
+ table['attributes'].each do |(_attribute_id, attribute)|
17
17
  @attributes << Attribute.new(attribute)
18
18
  end
19
+ @superclass = nil
20
+ @subclasses = []
21
+ end
22
+
23
+ def self.update_superclasses(parsed_tables)
24
+ all.each do |table|
25
+ superclass_id = parsed_tables[table.id]['superclassId']
26
+
27
+ next if superclass_id == ''
28
+
29
+ super_class = Table.find superclass_id
30
+ table.superclass = super_class
31
+ super_class.subclasses << table
32
+ end
19
33
  end
20
34
 
21
35
  def model_name
22
36
  name.camelize
23
37
  end
24
38
 
25
- def add_references(entity)
26
- command = "bundle exec rails generate migration Add#{entity.name.camelize}RefTo#{name.camelize} #{entity.name}:references"
39
+ def root_class
40
+ nil unless @superclass
41
+
42
+ root = self
43
+
44
+ root = root.superclass while root.superclass
45
+
46
+ root
47
+ end
48
+
49
+ def root_class?
50
+ !superclass
51
+ end
52
+
53
+ def generate_reference_migration(name, polymorphic = false)
54
+ command = "bundle exec rails generate migration Add#{name.camelize}RefTo#{root_class.name.camelize} #{name}:references"
55
+
56
+ command << '{polymorphic}' if polymorphic
27
57
 
28
58
  system(command)
29
59
  end
30
60
 
61
+ def add_polymorphic_reference_migration_for_sti
62
+ return unless superclass && polymorphic
63
+
64
+ polymorphic_names.each do |name|
65
+ generate_reference_migration(name, true)
66
+ end
67
+ end
68
+
31
69
  def add_polymorphic_reference(command, poly_name)
32
70
  command << " #{poly_name}:references{polymorphic}"
33
71
  end
34
72
 
35
73
  def update_polymorphic_names
36
- return if entities.size.zero?
74
+ return if entities.empty?
37
75
 
38
76
  belong_parents = []
39
77
  entities.each do |entity|
@@ -48,31 +86,35 @@ class Table < TableEntityBase
48
86
  belong_parent_names.count(parent_name) > 1
49
87
  end.uniq
50
88
 
51
- @polymorphic_names = filtered_parent_names.find_all do |parent_name|
89
+ self.polymorphic_names = filtered_parent_names.find_all do |parent_name|
52
90
  belong_parents.find_all do |entity|
53
91
  entity.name == parent_name
54
- end.map(&:clone_parent).map(&:name).uniq.size > 1
92
+ end.map(&:table).map(&:name).uniq.size > 1
55
93
  end
94
+
95
+ self.polymorphic = true if polymorphic_names.size.positive?
56
96
  end
57
97
 
58
98
  def check_polymorphic(command)
59
99
  update_polymorphic_names
60
- @polymorphic_names.each do |poly_name|
100
+ polymorphic_names.each do |poly_name|
61
101
  add_polymorphic_reference(command, poly_name)
62
102
  end
63
-
64
- @polymorphic = true if @polymorphic_names.size.positive?
65
103
  end
66
104
 
67
105
  def create_model
68
106
  return if File.exist?("./app/models/#{name}.rb")
69
107
 
70
- command = 'bundle exec rails generate model '
71
- command << model_name
72
- attributes.each { |attribute| attribute.add_to(command) }
108
+ command = "bundle exec rails generate model #{model_name}"
109
+
110
+ command << ' type' if subclasses.any? && root_class?
111
+
112
+ attributes.each { |attribute| attribute.add_to(command) } unless superclass
73
113
 
74
114
  check_polymorphic(command)
75
115
 
116
+ command << " --parent=#{superclass.name.classify}" if superclass
117
+
76
118
  system(command)
77
119
  end
78
120
 
@@ -81,7 +123,7 @@ class Table < TableEntityBase
81
123
  (entity.parents_has_many + entity.parents_has_one).each do |parent|
82
124
  next if entity.one_polymorphic_names?(parent)
83
125
 
84
- add_references(parent)
126
+ generate_reference_migration(parent.name)
85
127
  end
86
128
  end
87
129
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ead
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hasan Ozovali
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-08 00:00:00.000000000 Z
11
+ date: 2023-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -100,6 +100,20 @@ dependencies:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
102
  version: '1.13'
103
+ - !ruby/object:Gem::Dependency
104
+ name: simplecov
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 0.21.2
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 0.21.2
103
117
  description: The compiler updates/creates models and associations, used in a Ruby
104
118
  on Rails project, defined by EAD automatically.
105
119
  email: ozovalihasan@gmail.com
@@ -116,10 +130,12 @@ files:
116
130
  - lib/project_file.rb
117
131
  - lib/table.rb
118
132
  - lib/table_entity_base.rb
119
- homepage: https://rubygems.org/gems/ead
133
+ homepage: https://github.com/ozovalihasan/ead-g
120
134
  licenses:
121
135
  - MIT
122
136
  metadata:
137
+ homepage_uri: https://github.com/ozovalihasan/ead-g
138
+ source_code_uri: https://github.com/ozovalihasan/ead-g
123
139
  rubygems_mfa_required: 'true'
124
140
  post_install_message:
125
141
  rdoc_options: []