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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2df8e51695a6a96f2fc32f697985e96e6ae201bf52af9acffad5877d25128751
4
- data.tar.gz: 3ac8715b733383d6160bf229cb234b0df74e6edb1c9220d2caeb95132e1292db
3
+ metadata.gz: 5a7327d58f230e0a97c0f8f16bffd96668a739ec899cbee6fae940ce3df021d4
4
+ data.tar.gz: 377c2ad16ae2e2f8044f382852c4771c655ea81e11985f1560c64c6d8a26acca
5
5
  SHA512:
6
- metadata.gz: b605039cf58e47a07283d309dcc0dcbabe890314f94ee6c881b1825c26d6714ecbbc00814e119d14fcf7f3ca54b082a4ec7a1592005e39e556b57a155f5337e7
7
- data.tar.gz: 660965617e683a0ae03a1b1f053590262953d5ea6cb664eeff623c6daeff5b16ed6ab41eb8b7eacdbc07c072657ee6e18fc532254a60c50258397ae721f121b5
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.2.0
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.2.0
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.2.0
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