Class: DynamicActiveModel::Database

Inherits:
Object
  • Object
show all
Defined in:
lib/dynamic-active-model/database.rb

Overview

The Database class is responsible for connecting to a database and creating ActiveRecord models from its tables. It provides functionality for:

  • Table filtering (blacklist/whitelist)

  • Model creation and management

  • Model updates and extensions

Examples:

Basic Usage

db = DynamicActiveModel::Database.new(DB, database_config)
db.create_models!

Table Filtering

db.skip_table 'temporary_data'
db.include_table 'users'
db.create_models!

Model Updates

db.update_model(:users) do
  def full_name
    "#{first_name} #{last_name}"
  end
end

Defined Under Namespace

Classes: ModelUpdater

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_module, connection_options, base_class_name = nil) ⇒ Database

Initializes a new Database instance

Parameters:

  • base_module (Module)

    The namespace for created models

  • connection_options (Hash)

    Database connection options

  • base_class_name (String, nil) (defaults to: nil)

    Optional base class name for models



48
49
50
51
52
53
54
55
56
# File 'lib/dynamic-active-model/database.rb', line 48

def initialize(base_module, connection_options, base_class_name = nil)
  @factory = Factory.new(base_module, connection_options, base_class_name)
  @table_class_names = {}
  @skip_tables = []
  @skip_table_matchers = []
  @include_tables = []
  @include_table_matchers = []
  @models = []
end

Instance Attribute Details

#factoryFactory (readonly)

Returns Factory instance used for model creation.

Returns:

  • (Factory)

    Factory instance used for model creation



30
31
32
# File 'lib/dynamic-active-model/database.rb', line 30

def factory
  @factory
end

#modelsArray (readonly)

Returns List of created model classes.

Returns:

  • (Array)

    List of created model classes



33
34
35
# File 'lib/dynamic-active-model/database.rb', line 33

def models
  @models
end

#table_class_namesHash (readonly)

Returns Mapping of table names to custom class names.

Returns:

  • (Hash)

    Mapping of table names to custom class names



27
28
29
# File 'lib/dynamic-active-model/database.rb', line 27

def table_class_names
  @table_class_names
end

Instance Method Details

#create_models!Array

Creates ActiveRecord models for all included tables

Returns:

  • (Array)

    List of created model classes



99
100
101
102
103
104
105
106
# File 'lib/dynamic-active-model/database.rb', line 99

def create_models!
  @factory.base_class.connection.tables.each do |table_name|
    next if skip_table?(table_name)
    next unless include_table?(table_name)

    @models << @factory.create(table_name, @table_class_names[table_name])
  end
end

#disable_standard_table_inheritance!void Also known as: disable_sti!

This method returns an undefined value.

Disables Single Table Inheritance (STI) for all models



120
121
122
123
124
# File 'lib/dynamic-active-model/database.rb', line 120

def disable_standard_table_inheritance!
  models.each do |model|
    model.inheritance_column = :_type_disabled if model.attribute_names.include?('type')
  end
end

#get_model(table_name) ⇒ Class?

Finds a model by table name

Parameters:

  • table_name (String)

    Name of the table

Returns:

  • (Class, nil)

    The model class or nil if not found



130
131
132
133
# File 'lib/dynamic-active-model/database.rb', line 130

def get_model(table_name)
  table_name = table_name.to_s
  models.detect { |model| model.table_name == table_name }
end

#get_model!(table_name) ⇒ Class

Finds a model by table name, raising an error if not found

Parameters:

  • table_name (String)

    Name of the table

Returns:

  • (Class)

    The model class

Raises:



139
140
141
142
143
144
# File 'lib/dynamic-active-model/database.rb', line 139

def get_model!(table_name)
  model = get_model(table_name)
  return model if model

  raise ::DynamicActiveModel::ModelNotFound, "no model found for table #{table_name}"
end

#include_table(table) ⇒ Object

Adds a table to the whitelist

Parameters:

  • table (String, Regexp)

    Table name or pattern to include



76
77
78
79
80
81
82
# File 'lib/dynamic-active-model/database.rb', line 76

def include_table(table)
  if table.is_a?(Regexp)
    @include_table_matchers << table
  else
    @include_tables << table.to_s
  end
end

#include_tables(tables) ⇒ Object

Adds multiple tables to the whitelist

Parameters:

  • tables (Array<String, Regexp>)

    Table names or patterns to include



86
87
88
# File 'lib/dynamic-active-model/database.rb', line 86

def include_tables(tables)
  tables.each { |table| include_table(table) }
end

#included_tablesArray

Returns List of all included tables and patterns.

Returns:

  • (Array)

    List of all included tables and patterns



114
115
116
# File 'lib/dynamic-active-model/database.rb', line 114

def included_tables
  @include_tables + @include_table_matchers
end

#skip_table(table) ⇒ Object

Adds a table to the blacklist

Parameters:

  • table (String, Regexp)

    Table name or pattern to skip



60
61
62
63
64
65
66
# File 'lib/dynamic-active-model/database.rb', line 60

def skip_table(table)
  if table.is_a?(Regexp)
    @skip_table_matchers << table
  else
    @skip_tables << table.to_s
  end
end

#skip_tables(tables) ⇒ Object

Adds multiple tables to the blacklist

Parameters:

  • tables (Array<String, Regexp>)

    Table names or patterns to skip



70
71
72
# File 'lib/dynamic-active-model/database.rb', line 70

def skip_tables(tables)
  tables.each { |table| skip_table(table) }
end

#skipped_tablesArray

Returns List of all skipped tables and patterns.

Returns:

  • (Array)

    List of all skipped tables and patterns



109
110
111
# File 'lib/dynamic-active-model/database.rb', line 109

def skipped_tables
  @skip_tables + @skip_table_matchers
end

#table_class_name(table_name, class_name) ⇒ Object

Sets a custom class name for a table

Parameters:

  • table_name (String)

    Name of the table

  • class_name (String)

    Custom class name to use



93
94
95
# File 'lib/dynamic-active-model/database.rb', line 93

def table_class_name(table_name, class_name)
  @table_class_names[table_name.to_s] = class_name
end

#update_all_models(base_dir, ext = '.ext.rb') ⇒ void

This method returns an undefined value.

Updates all models using extension files from a directory

Parameters:

  • base_dir (String)

    Directory containing extension files

  • ext (String) (defaults to: '.ext.rb')

    Extension for model update files



162
163
164
165
166
167
168
169
# File 'lib/dynamic-active-model/database.rb', line 162

def update_all_models(base_dir, ext = '.ext.rb')
  Dir.glob("#{base_dir}/*#{ext}") do |file|
    next unless File.file?(file)

    table_name = File.basename(file).split('.', 2).first
    update_model(table_name, file)
  end
end

#update_model(table_name, file = nil, &block) ⇒ Class

Updates a model’s definition

Parameters:

  • table_name (String)

    Name of the table

  • file (String, nil) (defaults to: nil)

    Path to a file containing model updates

  • block (Proc)

    Code to evaluate in the model’s context

Returns:

  • (Class)

    The updated model class



151
152
153
154
155
156
# File 'lib/dynamic-active-model/database.rb', line 151

def update_model(table_name, file = nil, &block)
  model = get_model!(table_name)
  ModelUpdater.new(model).instance_eval(File.read(file)) if file
  model.class_eval(&block) if block
  model
end