activerecord-model_inheritance 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rubocop.yml +451 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +8 -0
- data/LICENSE +21 -0
- data/README.md +255 -0
- data/Rakefile +7 -0
- data/lib/active_record/model_inheritance/error.rb +5 -0
- data/lib/active_record/model_inheritance/model.rb +169 -0
- data/lib/active_record/model_inheritance/version.rb +5 -0
- data/lib/active_record/model_inheritance/view_definition.rb +112 -0
- data/lib/active_record/model_inheritance.rb +57 -0
- data/lib/activerecord/model_inheritance.rb +1 -0
- data/lib/generators/active_record/model_inheritance/generators.rb +6 -0
- data/lib/generators/active_record/model_inheritance/model/model_generator.rb +75 -0
- data/lib/generators/active_record/model_inheritance/model/templates/definition.erb +1 -0
- data/lib/generators/active_record/model_inheritance/model/templates/model.erb +2 -0
- data/lib/generators/active_record/model_inheritance/model/templates/model_config.erb +3 -0
- data/lib/generators/active_record/model_inheritance/view/templates/create_migration.erb +13 -0
- data/lib/generators/active_record/model_inheritance/view/templates/update_migration.erb +5 -0
- data/lib/generators/active_record/model_inheritance/view/view_generator.rb +121 -0
- data/sig/active_record/model_inheritance/generators/model_generator.rbs +23 -0
- data/sig/active_record/model_inheritance/generators/view_generator.rbs +45 -0
- data/sig/active_record/model_inheritance/version.rbs +5 -0
- data/sig/active_record/model_inheritance/view_definition.rbs +20 -0
- metadata +127 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'active_record/model_inheritance'
|
3
|
+
|
4
|
+
module ActiveRecord
|
5
|
+
module ModelInheritance
|
6
|
+
module Generators
|
7
|
+
class ModelGenerator < Rails::Generators::NamedBase
|
8
|
+
source_root File.expand_path('templates', __dir__)
|
9
|
+
|
10
|
+
desc 'Create derived model and definition files'
|
11
|
+
|
12
|
+
argument :derives_from, type: :string, optional: false
|
13
|
+
|
14
|
+
class_option :only_definition,
|
15
|
+
type: :boolean,
|
16
|
+
required: false,
|
17
|
+
default: false,
|
18
|
+
desc: 'Whether or not to generate only the definition file'
|
19
|
+
|
20
|
+
def generate_model
|
21
|
+
return if skip_generate_model?
|
22
|
+
|
23
|
+
if rails_application?
|
24
|
+
invoke 'model',
|
25
|
+
[file_path.singularize],
|
26
|
+
options.merge(
|
27
|
+
fixture_replacement: false,
|
28
|
+
migration: false
|
29
|
+
)
|
30
|
+
else
|
31
|
+
template 'model.erb', ModelInheritance.models_path.join("#{file_path.singularize}.rb")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def inject_configuration_to_model
|
36
|
+
return if skip_generate_model?
|
37
|
+
|
38
|
+
inject_into_class ModelInheritance.models_path.join("#{file_path.singularize}.rb"), class_name do
|
39
|
+
evaluate_template 'model_config.erb'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_definition_file
|
44
|
+
template 'definition.erb', ModelInheritance.definitions_path.join("#{table_name}.rb")
|
45
|
+
end
|
46
|
+
|
47
|
+
no_tasks do
|
48
|
+
def evaluate_template source
|
49
|
+
source = File.expand_path find_in_source_paths(source.to_s)
|
50
|
+
|
51
|
+
erb = ERB.new(
|
52
|
+
File.read(source),
|
53
|
+
trim_mode: '-',
|
54
|
+
eoutvar: '@output_buffer'
|
55
|
+
)
|
56
|
+
|
57
|
+
erb.result binding
|
58
|
+
end
|
59
|
+
|
60
|
+
def rails_application?
|
61
|
+
defined?(Rails.application) && Rails.application.present?
|
62
|
+
end
|
63
|
+
|
64
|
+
def skip_generate_model?
|
65
|
+
options[:only_definition]
|
66
|
+
end
|
67
|
+
|
68
|
+
def formatted_base_name
|
69
|
+
"::#{derives_from.camelize}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
ActiveRecord::ModelInheritance::ViewDefinition.define_derived_view <%= name %>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class <%= migration_class_name %> < <%= activerecord_migration_class %>
|
2
|
+
def change
|
3
|
+
create_table <%= formatted_inner_table_name %> do |t|
|
4
|
+
# add your derived model extra fields here
|
5
|
+
|
6
|
+
t.references <%= formatted_base_name %>, foreign_key: true
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
create_view <%= formatted_table_name %>
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/active_record'
|
3
|
+
require 'active_record/model_inheritance'
|
4
|
+
require 'active_record/model_inheritance/view_definition'
|
5
|
+
|
6
|
+
module ActiveRecord
|
7
|
+
module ModelInheritance
|
8
|
+
module Generators
|
9
|
+
class ViewGenerator < Rails::Generators::NamedBase
|
10
|
+
include Rails::Generators::Migration
|
11
|
+
|
12
|
+
desc 'Generate SQL view definition and create initial/update migration'
|
13
|
+
|
14
|
+
source_root File.expand_path('templates', __dir__)
|
15
|
+
|
16
|
+
class_option :skip_migration,
|
17
|
+
type: :boolean,
|
18
|
+
required: false,
|
19
|
+
default: false,
|
20
|
+
desc: 'Whether or not to generate a migration file'
|
21
|
+
|
22
|
+
def create_view_file
|
23
|
+
create_file ModelInheritance
|
24
|
+
.views_path
|
25
|
+
.join("#{table_name}_v#{formatted_next_version}.sql"),
|
26
|
+
view_definition.to_sql
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_migration_file
|
30
|
+
return if skip_generate_migration?
|
31
|
+
|
32
|
+
if creating?
|
33
|
+
migration_template(
|
34
|
+
'create_migration.erb',
|
35
|
+
ModelInheritance.migrations_path.join("create_#{table_name}.rb")
|
36
|
+
)
|
37
|
+
else
|
38
|
+
migration_template(
|
39
|
+
'update_migration.erb',
|
40
|
+
ModelInheritance.migrations_path.join("update_#{table_name}_to_version_#{formatted_next_version}.rb")
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.next_migration_number dir
|
46
|
+
::ActiveRecord::Generators::Base.next_migration_number dir
|
47
|
+
end
|
48
|
+
|
49
|
+
no_tasks do
|
50
|
+
def current_version
|
51
|
+
@current_version ||= ModelInheritance
|
52
|
+
.views_path
|
53
|
+
.glob("#{table_name}_v*.sql")
|
54
|
+
.last
|
55
|
+
.then { |last_version_file| last_version_file&.basename&.to_s }
|
56
|
+
.then do |last_version_name|
|
57
|
+
version_regex
|
58
|
+
.match(last_version_name)
|
59
|
+
.try(:[], :version)
|
60
|
+
.to_i
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def next_version
|
65
|
+
@next_version ||= current_version.next
|
66
|
+
end
|
67
|
+
|
68
|
+
def formatted_next_version
|
69
|
+
next_version
|
70
|
+
.to_s
|
71
|
+
.rjust(2, '0')
|
72
|
+
end
|
73
|
+
|
74
|
+
def creating?
|
75
|
+
current_version.zero?
|
76
|
+
end
|
77
|
+
|
78
|
+
def skip_generate_migration?
|
79
|
+
options[:skip_migration]
|
80
|
+
end
|
81
|
+
|
82
|
+
def version_regex
|
83
|
+
%r{\A#{table_name}_v(?<version>\d+)\.sql\z}
|
84
|
+
end
|
85
|
+
|
86
|
+
def formatted_class_name
|
87
|
+
class_name.tr('.:', '').pluralize
|
88
|
+
end
|
89
|
+
|
90
|
+
def migration_class_name
|
91
|
+
if creating?
|
92
|
+
"Create#{formatted_class_name}"
|
93
|
+
else
|
94
|
+
"Update#{formatted_class_name}ToVersion#{next_version}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def activerecord_migration_class
|
99
|
+
"ActiveRecord::Migration[#{ActiveRecord::Migration.current_version}]"
|
100
|
+
end
|
101
|
+
|
102
|
+
def formatted_inner_table_name
|
103
|
+
":#{view_definition.model_class.model_inheritance_inner_model.table_name}"
|
104
|
+
end
|
105
|
+
|
106
|
+
def formatted_base_name
|
107
|
+
":#{view_definition.model_class.model_inheritance_base_model.model_name.singular}"
|
108
|
+
end
|
109
|
+
|
110
|
+
def formatted_table_name
|
111
|
+
":#{table_name}"
|
112
|
+
end
|
113
|
+
|
114
|
+
def view_definition
|
115
|
+
@view_definition ||= ViewDefinition.from_name table_name
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ModelInheritance
|
3
|
+
module Generators
|
4
|
+
class ModelGenerator < Rails::Generators::NamedBase
|
5
|
+
def generate_model: () -> void
|
6
|
+
|
7
|
+
def inject_configuration_to_model: () -> void
|
8
|
+
|
9
|
+
def create_definition_file: () -> void
|
10
|
+
|
11
|
+
def evaluate_template: (String source) -> String
|
12
|
+
|
13
|
+
def rails_application?: () -> bool
|
14
|
+
|
15
|
+
def skip_generate_model?: () -> bool
|
16
|
+
|
17
|
+
def formatted_base_name: () -> String
|
18
|
+
|
19
|
+
def formatted_base_reference: () -> String
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ModelInheritance
|
3
|
+
module Generators
|
4
|
+
class ViewGenerator < Rails::Generators::NamedBase
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
|
7
|
+
@current_version: Integer
|
8
|
+
@next_version: Integer
|
9
|
+
@view_definition: ViewDefinition
|
10
|
+
|
11
|
+
def create_view_file: () -> void
|
12
|
+
|
13
|
+
def create_migration_file: () -> void
|
14
|
+
|
15
|
+
def self.next_migration_number: (untyped dir) -> untyped
|
16
|
+
|
17
|
+
def current_version: () -> Integer
|
18
|
+
|
19
|
+
def next_version: () -> Integer
|
20
|
+
|
21
|
+
def formatted_next_version: () -> String
|
22
|
+
|
23
|
+
def creating?: () -> bool
|
24
|
+
|
25
|
+
def skip_generate_migration?: () -> bool
|
26
|
+
|
27
|
+
def version_regex: () -> Regexp
|
28
|
+
|
29
|
+
def formatted_class_name: () -> String
|
30
|
+
|
31
|
+
def migration_class_name: () -> String
|
32
|
+
|
33
|
+
def activerecord_migration_class: () -> String
|
34
|
+
|
35
|
+
def formatted_inner_table_name: () -> String
|
36
|
+
|
37
|
+
def formatted_base_name: () -> String
|
38
|
+
|
39
|
+
def formatted_table_name: () -> String
|
40
|
+
|
41
|
+
def view_definition: () -> ViewDefinition
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ModelInheritance
|
3
|
+
class ViewDefinition
|
4
|
+
def initialize: (Class model_class, untyped definition) -> void
|
5
|
+
|
6
|
+
def self.define_derived_view: (Class model_class) -> ViewDefinition
|
7
|
+
|
8
|
+
def self.from_model: (Class model_class) -> ViewDefinition
|
9
|
+
|
10
|
+
def self.from_name: (String name) -> ViewDefinition
|
11
|
+
|
12
|
+
attr_reader definition: untyped
|
13
|
+
attr_reader model_class: Class
|
14
|
+
|
15
|
+
def attributes_mapping: -> {base: Array[Symbol], inner: Array[Symbol]}
|
16
|
+
|
17
|
+
def to_sql: -> String
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: activerecord-model_inheritance
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Moku S.r.l.
|
8
|
+
- Marco Volpato
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2023-07-10 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activerecord
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 7.0.0
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 7.0.0
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: activesupport
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 7.0.0
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 7.0.0
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: railties
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 7.0.0
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 7.0.0
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: scenic
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.7.0
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.7.0
|
70
|
+
description: An attempt at real inheritance for ActiveRecord models.
|
71
|
+
email:
|
72
|
+
- info@moku.io
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".rubocop.yml"
|
78
|
+
- CHANGELOG.md
|
79
|
+
- Gemfile
|
80
|
+
- LICENSE
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- lib/active_record/model_inheritance.rb
|
84
|
+
- lib/active_record/model_inheritance/error.rb
|
85
|
+
- lib/active_record/model_inheritance/model.rb
|
86
|
+
- lib/active_record/model_inheritance/version.rb
|
87
|
+
- lib/active_record/model_inheritance/view_definition.rb
|
88
|
+
- lib/activerecord/model_inheritance.rb
|
89
|
+
- lib/generators/active_record/model_inheritance/generators.rb
|
90
|
+
- lib/generators/active_record/model_inheritance/model/model_generator.rb
|
91
|
+
- lib/generators/active_record/model_inheritance/model/templates/definition.erb
|
92
|
+
- lib/generators/active_record/model_inheritance/model/templates/model.erb
|
93
|
+
- lib/generators/active_record/model_inheritance/model/templates/model_config.erb
|
94
|
+
- lib/generators/active_record/model_inheritance/view/templates/create_migration.erb
|
95
|
+
- lib/generators/active_record/model_inheritance/view/templates/update_migration.erb
|
96
|
+
- lib/generators/active_record/model_inheritance/view/view_generator.rb
|
97
|
+
- sig/active_record/model_inheritance/generators/model_generator.rbs
|
98
|
+
- sig/active_record/model_inheritance/generators/view_generator.rbs
|
99
|
+
- sig/active_record/model_inheritance/version.rbs
|
100
|
+
- sig/active_record/model_inheritance/view_definition.rbs
|
101
|
+
homepage: https://github.com/moku-io/activerecord-model_inheritance
|
102
|
+
licenses:
|
103
|
+
- MIT
|
104
|
+
metadata:
|
105
|
+
homepage_uri: https://github.com/moku-io/activerecord-model_inheritance
|
106
|
+
source_code_uri: https://github.com/moku-io/activerecord-model_inheritance
|
107
|
+
changelog_uri: https://github.com/moku-io/activerecord-model_inheritance/blob/master/CHANGELOG.md
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 3.0.0
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubygems_version: 3.3.26
|
124
|
+
signing_key:
|
125
|
+
specification_version: 4
|
126
|
+
summary: An attempt at real inheritance for ActiveRecord models.
|
127
|
+
test_files: []
|