dynamic-active-model-rails 1.2.0 → 1.3.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.md +18 -0
- data/lib/dynamic-active-model/rails/model_export.rb +24 -0
- data/lib/dynamic-active-model/rails/model_report.rb +64 -0
- data/lib/dynamic-active-model/rails/railtie.rb +4 -0
- data/lib/dynamic-active-model/rails/tasks/dynamic_active_model.rake +15 -0
- data/lib/dynamic-active-model/rails.rb +2 -0
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5a7327d58f230e0a97c0f8f16bffd96668a739ec899cbee6fae940ce3df021d4
|
|
4
|
+
data.tar.gz: 377c2ad16ae2e2f8044f382852c4771c655ea81e11985f1560c64c6d8a26acca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e2fcb3f0522925d95fedb76004ea695c13b618b525d22dff9726ac56c965811ceb2ef74ee8017d214b598a1e3c3201d5e088806ce54c1eab2ced77ce303715d2
|
|
7
|
+
data.tar.gz: d3dccaaf31a98ed51d446e27c5c5e7bcd6a728fb4d88c89b5aef4f2c35980a297096f08587cf38e010af035efa5d4e69131cd02b46a294db0a16358aaaa321ce
|
data/README.md
CHANGED
|
@@ -29,6 +29,24 @@ bin/rails generate dynamic_active_model:extension grant_db users # app/mod
|
|
|
29
29
|
|
|
30
30
|
`--connection NAME` points the database at a `database.yml` entry. `--replica NAME` adds a reading role through `connects_to` and requires `--connection`. The generators warn if the current environment has no such entry. Without `--connection`, the database shares `ApplicationRecord`'s connection.
|
|
31
31
|
|
|
32
|
+
## Rake Tasks
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bin/rails dynamic_active_model:models # each database with its models and associations
|
|
36
|
+
bin/rails dynamic_active_model:export DIR=tmp/models # a class file per model (default tmp/dynamic_active_model)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`models` shows what the gem generated, without opening a console:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
GrantDB (shares ApplicationRecord's connection), 31 models
|
|
43
|
+
GrantDB::Role (roles)
|
|
44
|
+
has_many :user_roles -> GrantDB::UserRole
|
|
45
|
+
has_many :users -> GrantDB::User, through: :user_roles
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Connections given as a URL or config hash are shown as "custom connection", so credentials never appear in the output. `export` writes `DIR/<namespace>/<model>.rb` for every model. Use it to read the generated associations, or as a starting point when a table needs a hand-written model.
|
|
49
|
+
|
|
32
50
|
## Configuration
|
|
33
51
|
|
|
34
52
|
```ruby
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DynamicActiveModel
|
|
4
|
+
module Rails
|
|
5
|
+
# Writes a class file per model (TemplateClassFile) for every declared
|
|
6
|
+
# database, for bin/rails dynamic_active_model:export. Useful to read what
|
|
7
|
+
# the gem generates, or as a starting point for a hand-written model.
|
|
8
|
+
class ModelExport
|
|
9
|
+
# @param loaders [Array<DatabaseLoader>]
|
|
10
|
+
def initialize(loaders)
|
|
11
|
+
@loaders = loaders
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @param dir [String] Output directory; files land in dir/<namespace>/<model>.rb
|
|
15
|
+
# @return [Array<String>] Paths written
|
|
16
|
+
def export!(dir)
|
|
17
|
+
@loaders.flat_map { |loader| loader.load!.models }.map do |model|
|
|
18
|
+
DynamicActiveModel::TemplateClassFile.new(model).create_template!(dir)
|
|
19
|
+
File.join(dir, "#{model.name.underscore}.rb")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DynamicActiveModel
|
|
4
|
+
module Rails
|
|
5
|
+
# A plain-text listing of each declared database's models and associations,
|
|
6
|
+
# for bin/rails dynamic_active_model:models. Builds the databases it lists.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# GrantDB (shares ApplicationRecord's connection), 2 models
|
|
10
|
+
# GrantDB::Role (roles)
|
|
11
|
+
# has_many :users -> GrantDB::User, through: :user_roles
|
|
12
|
+
class ModelReport
|
|
13
|
+
# @param loaders [Array<DatabaseLoader>]
|
|
14
|
+
def initialize(loaders)
|
|
15
|
+
@loaders = loaders
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @return [String]
|
|
19
|
+
def to_s
|
|
20
|
+
@loaders.map { |loader| database_section(loader) }.join("\n")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
# @param loader [DatabaseLoader]
|
|
26
|
+
# @return [String]
|
|
27
|
+
def database_section(loader)
|
|
28
|
+
models = loader.load!.models.sort_by(&:name)
|
|
29
|
+
lines = ["#{loader.definition.module_name} (#{connection_description(loader.definition)}), " \
|
|
30
|
+
"#{models.size} #{models.size == 1 ? 'model' : 'models'}"]
|
|
31
|
+
models.each { |model| lines.concat(model_lines(model)) }
|
|
32
|
+
"#{lines.join("\n")}\n"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Describes the connection without printing URLs or config hashes, which
|
|
36
|
+
# can hold passwords
|
|
37
|
+
# @param definition [DatabaseDefinition]
|
|
38
|
+
# @return [String]
|
|
39
|
+
def connection_description(definition)
|
|
40
|
+
return "connects_to: #{definition.connects_to.inspect}" if definition.connects_to
|
|
41
|
+
return "connection: #{definition.connection.inspect}" if definition.connection.is_a?(Symbol)
|
|
42
|
+
return 'custom connection' if definition.connection
|
|
43
|
+
|
|
44
|
+
"shares #{definition.parent_class_name}'s connection"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @param model [Class]
|
|
48
|
+
# @return [Array<String>]
|
|
49
|
+
def model_lines(model)
|
|
50
|
+
[" #{model.name} (#{model.table_name})"] +
|
|
51
|
+
model.reflect_on_all_associations.sort_by { |reflection| reflection.name.to_s }.map do |reflection|
|
|
52
|
+
" #{association_line(reflection)}"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @param reflection [ActiveRecord::Reflection::AssociationReflection]
|
|
57
|
+
# @return [String] e.g. "has_many :users -> GrantDB::User, through: :user_roles"
|
|
58
|
+
def association_line(reflection)
|
|
59
|
+
line = "#{reflection.macro} #{reflection.name.inspect} -> #{reflection.klass.name}"
|
|
60
|
+
reflection.options[:through] ? "#{line}, through: #{reflection.options[:through].inspect}" : line
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -7,6 +7,10 @@ module DynamicActiveModel
|
|
|
7
7
|
class Railtie < ::Rails::Railtie
|
|
8
8
|
config.eager_load_namespaces << DynamicActiveModel::Rails
|
|
9
9
|
|
|
10
|
+
rake_tasks do
|
|
11
|
+
load File.expand_path('tasks/dynamic_active_model.rake', __dir__)
|
|
12
|
+
end
|
|
13
|
+
|
|
10
14
|
# so config.active_support.deprecation (log, raise in tests, ...) applies
|
|
11
15
|
initializer 'dynamic_active_model.deprecator' do |app|
|
|
12
16
|
app.deprecators[:dynamic_active_model] = DynamicActiveModel.deprecator
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :dynamic_active_model do
|
|
4
|
+
desc 'List each declared database with its models and associations'
|
|
5
|
+
task models: :environment do
|
|
6
|
+
puts DynamicActiveModel::Rails::ModelReport.new(DynamicActiveModel::Rails.loaders)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
desc 'Write a class file per model to DIR (default tmp/dynamic_active_model)'
|
|
10
|
+
task export: :environment do
|
|
11
|
+
dir = ENV.fetch('DIR') { Rails.root.join('tmp', 'dynamic_active_model').to_s }
|
|
12
|
+
files = DynamicActiveModel::Rails::ModelExport.new(DynamicActiveModel::Rails.loaders).export!(dir)
|
|
13
|
+
puts "Wrote #{files.size} class files to #{dir}"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -21,6 +21,8 @@ module DynamicActiveModel
|
|
|
21
21
|
autoload :DatabaseDefinition, 'dynamic-active-model/rails/database_definition'
|
|
22
22
|
autoload :DatabaseLoader, 'dynamic-active-model/rails/database_loader'
|
|
23
23
|
autoload :LazyNamespace, 'dynamic-active-model/rails/lazy_namespace'
|
|
24
|
+
autoload :ModelExport, 'dynamic-active-model/rails/model_export'
|
|
25
|
+
autoload :ModelReport, 'dynamic-active-model/rails/model_report'
|
|
24
26
|
autoload :SchemaChangeHook, 'dynamic-active-model/rails/schema_change_hook'
|
|
25
27
|
|
|
26
28
|
class << self
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dynamic-active-model-rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Doug Youch
|
|
@@ -29,14 +29,14 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - '='
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 1.
|
|
32
|
+
version: 1.3.0
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - '='
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: 1.
|
|
39
|
+
version: 1.3.0
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: railties
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -67,8 +67,11 @@ files:
|
|
|
67
67
|
- lib/dynamic-active-model/rails/database_definition.rb
|
|
68
68
|
- lib/dynamic-active-model/rails/database_loader.rb
|
|
69
69
|
- lib/dynamic-active-model/rails/lazy_namespace.rb
|
|
70
|
+
- lib/dynamic-active-model/rails/model_export.rb
|
|
71
|
+
- lib/dynamic-active-model/rails/model_report.rb
|
|
70
72
|
- lib/dynamic-active-model/rails/railtie.rb
|
|
71
73
|
- lib/dynamic-active-model/rails/schema_change_hook.rb
|
|
74
|
+
- lib/dynamic-active-model/rails/tasks/dynamic_active_model.rake
|
|
72
75
|
- lib/generators/dynamic_active_model/database/database_generator.rb
|
|
73
76
|
- lib/generators/dynamic_active_model/database_arguments.rb
|
|
74
77
|
- lib/generators/dynamic_active_model/extension/extension_generator.rb
|