Module: AIFaker::ModelIntrospector
- Defined in:
- lib/AIFaker/model_introspector.rb
Class Method Summary collapse
- .app_models ⇒ Object
- .describe_associations(model) ⇒ Object
- .describe_model(model) ⇒ Object
- .describe_models_and_associations ⇒ Object
- .eager_load_models! ⇒ Object
- .ensure_active_record! ⇒ Object
Class Method Details
.app_models ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/AIFaker/model_introspector.rb', line 46 def app_models base = if defined?(ApplicationRecord) ApplicationRecord else ActiveRecord::Base end base.descendants .reject(&:abstract_class?) .reject { |m| m.name.nil? || m.name.empty? } .sort_by(&:name) end |
.describe_associations(model) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/AIFaker/model_introspector.rb', line 76 def describe_associations(model) model.reflections.values.map do |r| { name: r.name.to_s, macro: r.macro.to_s, class_name: r.class_name.to_s, foreign_key: r.foreign_key.to_s, optional: (r.respond_to?(:options) ? !!r.[:optional] : false) } end end |
.describe_model(model) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/AIFaker/model_introspector.rb', line 60 def describe_model(model) { name: model.name, table_name: model.table_name, primary_key: model.primary_key, columns: model.columns.map do |c| { name: c.name, type: c.type.to_s, null: c.null, default: c.default } end } end |
.describe_models_and_associations ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/AIFaker/model_introspector.rb', line 7 def describe_models_and_associations ensure_active_record! eager_load_models! models = app_models associations = models.to_h { |m| [m.name, describe_associations(m)] } { models: models.map { |m| describe_model(m) }, associations: } end |
.eager_load_models! ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/AIFaker/model_introspector.rb', line 26 def eager_load_models! return unless defined?(Rails) && Rails.respond_to?(:application) && Rails.application # In development, Rails often doesn't eager-load models, so descendants can be empty. # We force-load model files so association introspection works during `db:seed`. Rails.application.eager_load! models_dir = Rails.root.join("app/models") loader = if defined?(ActiveSupport::Dependencies) && ActiveSupport::Dependencies.respond_to?(:require_dependency) ActiveSupport::Dependencies.method(:require_dependency) else method(:require) end Dir.glob(models_dir.join("**/*.rb")).sort.each { |f| loader.call(f) } rescue LoadError, StandardError # best-effort; not fatal (but if this fails, seeding may not see all models) end |
.ensure_active_record! ⇒ Object
20 21 22 23 24 |
# File 'lib/AIFaker/model_introspector.rb', line 20 def ensure_active_record! return if defined?(ActiveRecord::Base) raise MissingRailsError, "ActiveRecord is not loaded. Run AIFaker from a Rails app." end |