dynamic-active-model 0.9.0 → 0.10.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/lib/dynamic-active-model/associations.rb +1 -1
- data/lib/dynamic-active-model/database.rb +29 -4
- data/lib/dynamic-active-model/explorer.rb +8 -4
- data/lib/dynamic-active-model/factory.rb +44 -10
- data/lib/dynamic-active-model/setup.rb +35 -26
- data/lib/dynamic-active-model/template_class_file.rb +11 -46
- data/lib/dynamic-active-model/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 58dbefec4f0c5d98abe3cab906e9e94aa288bca95f40215569b5dabd62ba27ec
|
|
4
|
+
data.tar.gz: 98e8408169aad9ea42161a878300205e030bf70d4e43eea6bb888a03d5096cbd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f4ddf3e3c10815ccf36c6e75c247b2f18e2e5b3dce896fd0ce8323f94910e063cc143e7013394a5eb61c373d72304b6799bde9b699ede968a1188e06969f4f5d
|
|
7
|
+
data.tar.gz: d062f596b4280e184d82a79e28f1eb5a8a0e310e408a179ef5d95df7153dbc0b9a1d522e5cf8d0639eb3b83e8ed2f4f752d353a209fc2f5cdf0fda5fc55ac264
|
|
@@ -76,7 +76,7 @@ module DynamicActiveModel
|
|
|
76
76
|
|
|
77
77
|
@join_tables.each do |join_table_model|
|
|
78
78
|
models = join_table_model.column_names.map do |column_name|
|
|
79
|
-
foreign_key_to_models
|
|
79
|
+
foreign_key_to_models.dig(column_name.downcase, 0, 0)
|
|
80
80
|
end.compact
|
|
81
81
|
add_has_and_belongs_to_many(join_table_model, models) if models.size == 2
|
|
82
82
|
end
|
|
@@ -16,6 +16,10 @@ module DynamicActiveModel
|
|
|
16
16
|
# db.include_table 'users'
|
|
17
17
|
# db.create_models!
|
|
18
18
|
#
|
|
19
|
+
# @example Rebuilding After a Schema Change
|
|
20
|
+
# db.reset!
|
|
21
|
+
# db.create_models!
|
|
22
|
+
#
|
|
19
23
|
# @example Model Updates
|
|
20
24
|
# db.update_model(:users) do
|
|
21
25
|
# def full_name
|
|
@@ -45,8 +49,9 @@ module DynamicActiveModel
|
|
|
45
49
|
# @param base_module [Module] The namespace for created models
|
|
46
50
|
# @param connection_options [Hash] Database connection options
|
|
47
51
|
# @param base_class_name [String, nil] Optional base class name for models
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
# @param parent_class [Class, nil] Optional superclass for the base class (see Factory)
|
|
53
|
+
def initialize(base_module, connection_options, base_class_name = nil, parent_class: nil)
|
|
54
|
+
@factory = Factory.new(base_module, connection_options, base_class_name, parent_class: parent_class)
|
|
50
55
|
@table_class_names = {}
|
|
51
56
|
@skip_tables = []
|
|
52
57
|
@skip_table_matchers = []
|
|
@@ -106,6 +111,15 @@ module DynamicActiveModel
|
|
|
106
111
|
@models
|
|
107
112
|
end
|
|
108
113
|
|
|
114
|
+
# Removes every created model constant and the factory's base class so the
|
|
115
|
+
# next call to #create_models! rebuilds them, e.g. after a schema change
|
|
116
|
+
# @return [void]
|
|
117
|
+
def reset!
|
|
118
|
+
@models.each { |model| @factory.remove(model) }
|
|
119
|
+
@models.clear
|
|
120
|
+
@factory.reset!
|
|
121
|
+
end
|
|
122
|
+
|
|
109
123
|
# @return [Array] List of all skipped tables and patterns
|
|
110
124
|
def skipped_tables
|
|
111
125
|
@skip_tables + @skip_table_matchers
|
|
@@ -182,11 +196,22 @@ module DynamicActiveModel
|
|
|
182
196
|
!skip_table?(table_name) && include_table?(table_name) && get_model(table_name).nil?
|
|
183
197
|
end
|
|
184
198
|
|
|
185
|
-
# Checks if a table
|
|
199
|
+
# Checks if a table is one of ActiveRecord's bookkeeping tables
|
|
200
|
+
# (schema_migrations, ar_internal_metadata)
|
|
201
|
+
# @param table_name [String] Name of the table
|
|
202
|
+
# @return [Boolean] Whether the table is internal to ActiveRecord
|
|
203
|
+
def internal_table?(table_name)
|
|
204
|
+
base_class = @factory.base_class
|
|
205
|
+
[base_class.schema_migrations_table_name, base_class.internal_metadata_table_name].include?(table_name)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Checks if a table should be skipped. ActiveRecord's internal tables are
|
|
209
|
+
# skipped unless included by exact name.
|
|
186
210
|
# @param table_name [String] Name of the table
|
|
187
211
|
# @return [Boolean] Whether the table should be skipped
|
|
188
212
|
def skip_table?(table_name)
|
|
189
|
-
|
|
213
|
+
(internal_table?(table_name) && !@include_tables.include?(table_name)) ||
|
|
214
|
+
@skip_tables.include?(table_name.to_s) ||
|
|
190
215
|
@skip_table_matchers.any? { |r| r.match(table_name) }
|
|
191
216
|
end
|
|
192
217
|
|
|
@@ -29,10 +29,13 @@ module DynamicActiveModel
|
|
|
29
29
|
# @param skip_tables [Array<String, Regexp>] Tables to exclude from model creation
|
|
30
30
|
# @param relationships [Hash] Custom foreign key relationships to add
|
|
31
31
|
# @param table_class_names [Hash] Custom class names by table name
|
|
32
|
+
# @param parent_class [Class, nil] Optional superclass for the base class (see Factory)
|
|
32
33
|
# @return [Database] The configured database instance
|
|
33
34
|
# @raise [ClassNameConflict] If two tables map to the same class name
|
|
34
|
-
def self.explore(base_module, connection_options, skip_tables = [], relationships = {}, table_class_names = {}
|
|
35
|
-
|
|
35
|
+
def self.explore(base_module, connection_options, skip_tables = [], relationships = {}, table_class_names = {},
|
|
36
|
+
parent_class: nil)
|
|
37
|
+
database = create_models!(base_module, connection_options, skip_tables, table_class_names,
|
|
38
|
+
parent_class: parent_class)
|
|
36
39
|
build_relationships!(database, relationships)
|
|
37
40
|
database
|
|
38
41
|
end
|
|
@@ -42,9 +45,10 @@ module DynamicActiveModel
|
|
|
42
45
|
# @param connection_options [Hash] Database connection options
|
|
43
46
|
# @param skip_tables [Array<String, Regexp>] Tables to exclude from model creation
|
|
44
47
|
# @param table_class_names [Hash] Custom class names by table name
|
|
48
|
+
# @param parent_class [Class, nil] Optional superclass for the base class (see Factory)
|
|
45
49
|
# @return [Database] The configured database instance
|
|
46
|
-
def self.create_models!(base_module, connection_options, skip_tables, table_class_names = {})
|
|
47
|
-
database = Database.new(base_module, connection_options)
|
|
50
|
+
def self.create_models!(base_module, connection_options, skip_tables, table_class_names = {}, parent_class: nil)
|
|
51
|
+
database = Database.new(base_module, connection_options, parent_class: parent_class)
|
|
48
52
|
skip_tables.each { |table| database.skip_table(skip_table_matcher(table)) }
|
|
49
53
|
table_class_names.each { |table_name, class_name| database.table_class_name(table_name, class_name) }
|
|
50
54
|
database.create_models!
|
|
@@ -15,6 +15,10 @@ module DynamicActiveModel
|
|
|
15
15
|
# @example With Custom Class Name
|
|
16
16
|
# factory = DynamicActiveModel::Factory.new(DB, database_config)
|
|
17
17
|
# model = factory.create('users', 'CustomUser')
|
|
18
|
+
#
|
|
19
|
+
# @example Sharing an Existing Connection Pool
|
|
20
|
+
# factory = DynamicActiveModel::Factory.new(DB, nil, parent_class: ApplicationRecord)
|
|
21
|
+
# model = factory.create('users')
|
|
18
22
|
class Factory
|
|
19
23
|
# @return [Class] The base class for all generated models
|
|
20
24
|
attr_writer :base_class
|
|
@@ -23,10 +27,13 @@ module DynamicActiveModel
|
|
|
23
27
|
# @param base_module [Module] The namespace for created models
|
|
24
28
|
# @param connection_options [Hash] Database connection options
|
|
25
29
|
# @param base_class_name [Symbol, nil] Optional name for the base class
|
|
26
|
-
|
|
30
|
+
# @param parent_class [Class, nil] Optional superclass for the base class. When given
|
|
31
|
+
# without connection options, the base class inherits the parent's connection.
|
|
32
|
+
def initialize(base_module, connection_options, base_class_name = nil, parent_class: nil)
|
|
27
33
|
@base_module = base_module
|
|
28
34
|
@connection_options = connection_options
|
|
29
35
|
@base_class_name = base_class_name || :DynamicAbstractBase
|
|
36
|
+
@parent_class = parent_class
|
|
30
37
|
end
|
|
31
38
|
|
|
32
39
|
# Creates a new model class for a table if it doesn't exist
|
|
@@ -56,8 +63,8 @@ module DynamicActiveModel
|
|
|
56
63
|
|
|
57
64
|
# Gets or creates the base class for all models
|
|
58
65
|
# This method:
|
|
59
|
-
# 1. Creates an abstract
|
|
60
|
-
# 2. Establishes the database connection
|
|
66
|
+
# 1. Creates an abstract subclass of the parent class if needed
|
|
67
|
+
# 2. Establishes the database connection, unless inheriting the parent's
|
|
61
68
|
# 3. Returns the configured base class
|
|
62
69
|
# @return [Class] The base class for all models
|
|
63
70
|
def base_class
|
|
@@ -65,19 +72,30 @@ module DynamicActiveModel
|
|
|
65
72
|
begin
|
|
66
73
|
require 'active_record'
|
|
67
74
|
|
|
68
|
-
unless @base_module.const_defined?(@base_class_name)
|
|
69
|
-
new_base_class = Class.new(ActiveRecord::Base) do
|
|
70
|
-
self.abstract_class = true
|
|
71
|
-
end
|
|
72
|
-
@base_module.const_set(@base_class_name, new_base_class)
|
|
73
|
-
end
|
|
75
|
+
define_base_class unless @base_module.const_defined?(@base_class_name)
|
|
74
76
|
|
|
75
77
|
@base_module.const_get(@base_class_name).tap do |kls|
|
|
76
|
-
kls.establish_connection
|
|
78
|
+
kls.establish_connection(@connection_options) if establish_connection?
|
|
77
79
|
end
|
|
78
80
|
end
|
|
79
81
|
end
|
|
80
82
|
|
|
83
|
+
# Removes a model's constant from the base module
|
|
84
|
+
# @param model [Class] A model class created by this factory
|
|
85
|
+
# @return [void]
|
|
86
|
+
def remove(model)
|
|
87
|
+
@base_module.send(:remove_const, model.name.demodulize)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Removes the base class constant if this factory defined it and forgets the
|
|
91
|
+
# cached base class, so the next call to #base_class builds a fresh one
|
|
92
|
+
# @return [void]
|
|
93
|
+
def reset!
|
|
94
|
+
@base_module.send(:remove_const, @base_class_name) if @defined_base_class
|
|
95
|
+
@defined_base_class = false
|
|
96
|
+
@base_class = nil
|
|
97
|
+
end
|
|
98
|
+
|
|
81
99
|
# Generates a valid Ruby class name from a table name
|
|
82
100
|
# @param table_name [String] Name of the database table
|
|
83
101
|
# @return [String] A valid Ruby class name
|
|
@@ -90,6 +108,22 @@ module DynamicActiveModel
|
|
|
90
108
|
|
|
91
109
|
private
|
|
92
110
|
|
|
111
|
+
# Defines the abstract base class in the base module
|
|
112
|
+
# @return [void]
|
|
113
|
+
def define_base_class
|
|
114
|
+
new_base_class = Class.new(@parent_class || ActiveRecord::Base) do
|
|
115
|
+
self.abstract_class = true
|
|
116
|
+
end
|
|
117
|
+
@base_module.const_set(@base_class_name, new_base_class)
|
|
118
|
+
@defined_base_class = true
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Checks if the base class needs its own connection
|
|
122
|
+
# @return [Boolean] False when inheriting the parent class's connection
|
|
123
|
+
def establish_connection?
|
|
124
|
+
@parent_class.nil? || !@connection_options.nil?
|
|
125
|
+
end
|
|
126
|
+
|
|
93
127
|
# Returns the existing model for a class name if it belongs to the table
|
|
94
128
|
# @param table_name [String] Name of the database table
|
|
95
129
|
# @param class_name [String] Name of the existing class
|
|
@@ -18,6 +18,13 @@ module DynamicActiveModel
|
|
|
18
18
|
# create_models!
|
|
19
19
|
# end
|
|
20
20
|
#
|
|
21
|
+
# @example Sharing ApplicationRecord's Connection
|
|
22
|
+
# module DB
|
|
23
|
+
# include DynamicActiveModel::Setup
|
|
24
|
+
# parent_class ApplicationRecord
|
|
25
|
+
# create_models!
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
21
28
|
# @example With Custom Relationships
|
|
22
29
|
# module DB
|
|
23
30
|
# include DynamicActiveModel::Setup
|
|
@@ -45,6 +52,7 @@ module DynamicActiveModel
|
|
|
45
52
|
def dynamic_active_model_config
|
|
46
53
|
{
|
|
47
54
|
connection_options: nil,
|
|
55
|
+
parent_class: nil,
|
|
48
56
|
skip_tables: [],
|
|
49
57
|
relationships: {},
|
|
50
58
|
table_class_names: {},
|
|
@@ -68,24 +76,25 @@ module DynamicActiveModel
|
|
|
68
76
|
.configuration_hash
|
|
69
77
|
end
|
|
70
78
|
|
|
71
|
-
if options
|
|
72
|
-
config = dynamic_active_model_config
|
|
73
|
-
config[:connection_options] = options
|
|
74
|
-
redefine_class_method(:dynamic_active_model_config, config)
|
|
75
|
-
end
|
|
79
|
+
update_config(:connection_options, options) if options
|
|
76
80
|
|
|
77
81
|
dynamic_active_model_config[:connection_options]
|
|
78
82
|
end
|
|
79
83
|
|
|
84
|
+
# Sets or gets the superclass for the generated base class. Without connection
|
|
85
|
+
# options, models inherit the parent class's connection.
|
|
86
|
+
# @param klass [Class, nil] Superclass, e.g. ApplicationRecord
|
|
87
|
+
# @return [Class, nil] The current parent class
|
|
88
|
+
def parent_class(klass = nil)
|
|
89
|
+
update_config(:parent_class, klass) if klass
|
|
90
|
+
dynamic_active_model_config[:parent_class]
|
|
91
|
+
end
|
|
92
|
+
|
|
80
93
|
# Sets or gets the list of tables to skip
|
|
81
94
|
# @param tables [Array<String>, nil] Tables to skip
|
|
82
95
|
# @return [Array<String>] The current list of skipped tables
|
|
83
96
|
def skip_tables(tables = nil)
|
|
84
|
-
if tables
|
|
85
|
-
config = dynamic_active_model_config
|
|
86
|
-
config[:skip_tables] = tables
|
|
87
|
-
redefine_class_method(:dynamic_active_model_config, config)
|
|
88
|
-
end
|
|
97
|
+
update_config(:skip_tables, tables) if tables
|
|
89
98
|
dynamic_active_model_config[:skip_tables]
|
|
90
99
|
end
|
|
91
100
|
|
|
@@ -101,11 +110,7 @@ module DynamicActiveModel
|
|
|
101
110
|
# @param all_relationships [Hash, nil] All custom relationships
|
|
102
111
|
# @return [Hash] The current relationships
|
|
103
112
|
def relationships(all_relationships = nil)
|
|
104
|
-
if all_relationships
|
|
105
|
-
config = dynamic_active_model_config
|
|
106
|
-
config[:relationships] = all_relationships
|
|
107
|
-
redefine_class_method(:dynamic_active_model_config, config)
|
|
108
|
-
end
|
|
113
|
+
update_config(:relationships, all_relationships) if all_relationships
|
|
109
114
|
dynamic_active_model_config[:relationships]
|
|
110
115
|
end
|
|
111
116
|
|
|
@@ -140,11 +145,7 @@ module DynamicActiveModel
|
|
|
140
145
|
# @param path [String, nil] Path to extension files
|
|
141
146
|
# @return [String, nil] The current extensions path
|
|
142
147
|
def extensions_path(path = nil)
|
|
143
|
-
if path
|
|
144
|
-
config = dynamic_active_model_config
|
|
145
|
-
config[:extensions_path] = path
|
|
146
|
-
redefine_class_method(:dynamic_active_model_config, config)
|
|
147
|
-
end
|
|
148
|
+
update_config(:extensions_path, path) if path
|
|
148
149
|
dynamic_active_model_config[:extensions_path]
|
|
149
150
|
end
|
|
150
151
|
|
|
@@ -152,11 +153,7 @@ module DynamicActiveModel
|
|
|
152
153
|
# @param suffix [String, nil] File extension suffix
|
|
153
154
|
# @return [String] The current extensions suffix
|
|
154
155
|
def extensions_suffix(suffix = nil)
|
|
155
|
-
if suffix
|
|
156
|
-
config = dynamic_active_model_config
|
|
157
|
-
config[:extensions_suffix] = suffix
|
|
158
|
-
redefine_class_method(:dynamic_active_model_config, config)
|
|
159
|
-
end
|
|
156
|
+
update_config(:extensions_suffix, suffix) if suffix
|
|
160
157
|
dynamic_active_model_config[:extensions_suffix]
|
|
161
158
|
end
|
|
162
159
|
|
|
@@ -173,12 +170,24 @@ module DynamicActiveModel
|
|
|
173
170
|
connection_options,
|
|
174
171
|
skip_tables,
|
|
175
172
|
relationships,
|
|
176
|
-
table_class_names
|
|
173
|
+
table_class_names,
|
|
174
|
+
parent_class: parent_class
|
|
177
175
|
)
|
|
178
176
|
)
|
|
179
177
|
database.update_all_models(extensions_path, extensions_suffix) if extensions_path
|
|
180
178
|
database
|
|
181
179
|
end
|
|
180
|
+
|
|
181
|
+
private
|
|
182
|
+
|
|
183
|
+
# Stores a single configuration value
|
|
184
|
+
# @param key [Symbol] Configuration key
|
|
185
|
+
# @param value [Object] Configuration value
|
|
186
|
+
def update_config(key, value)
|
|
187
|
+
config = dynamic_active_model_config
|
|
188
|
+
config[key] = value
|
|
189
|
+
redefine_class_method(:dynamic_active_model_config, config)
|
|
190
|
+
end
|
|
182
191
|
end
|
|
183
192
|
end
|
|
184
193
|
end
|
|
@@ -42,16 +42,17 @@ module DynamicActiveModel
|
|
|
42
42
|
str << " self.table_name = #{@model.table_name.to_sym.inspect}\n"
|
|
43
43
|
end
|
|
44
44
|
all_has_many_relationships.each do |assoc|
|
|
45
|
-
append_association!(str, assoc)
|
|
45
|
+
append_association!(str, 'has_many', assoc, has_many_association_options(assoc))
|
|
46
46
|
end
|
|
47
47
|
all_belongs_to_relationships.each do |assoc|
|
|
48
|
-
append_association!(str, assoc)
|
|
48
|
+
append_association!(str, 'belongs_to', assoc, belongs_to_association_options(assoc))
|
|
49
49
|
end
|
|
50
50
|
all_has_one_relationships.each do |assoc|
|
|
51
|
-
append_association!(str, assoc)
|
|
51
|
+
append_association!(str, 'has_one', assoc, has_one_association_options(assoc))
|
|
52
52
|
end
|
|
53
53
|
all_has_and_belongs_to_many_relationships.each do |assoc|
|
|
54
|
-
append_association!(str, assoc
|
|
54
|
+
append_association!(str, 'has_and_belongs_to_many', assoc,
|
|
55
|
+
has_and_belongs_to_many_association_options(assoc))
|
|
55
56
|
end
|
|
56
57
|
str << "end\n"
|
|
57
58
|
str
|
|
@@ -85,35 +86,13 @@ module DynamicActiveModel
|
|
|
85
86
|
|
|
86
87
|
# Appends an association definition to the source string
|
|
87
88
|
# @param str [String] The source string being built
|
|
89
|
+
# @param assoc_type [String] The association macro, e.g. 'has_many'
|
|
88
90
|
# @param assoc [ActiveRecord::Reflection::AssociationReflection] The association to add
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
when ActiveRecord::Reflection::HasManyReflection
|
|
92
|
-
'has_many'
|
|
93
|
-
when ActiveRecord::Reflection::BelongsToReflection
|
|
94
|
-
'belongs_to'
|
|
95
|
-
when ActiveRecord::Reflection::HasOneReflection
|
|
96
|
-
'has_one'
|
|
97
|
-
when ActiveRecord::Reflection::HasAndBelongsToManyReflection
|
|
98
|
-
'has_and_belongs_to_many'
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
association_options = case assoc_type
|
|
102
|
-
when 'has_many'
|
|
103
|
-
has_many_association_options(assoc)
|
|
104
|
-
when 'belongs_to'
|
|
105
|
-
belongs_to_association_options(assoc)
|
|
106
|
-
when 'has_one'
|
|
107
|
-
has_one_association_options(assoc)
|
|
108
|
-
when 'has_and_belongs_to_many'
|
|
109
|
-
has_and_belongs_to_many_association_options(assoc)
|
|
110
|
-
end
|
|
111
|
-
|
|
91
|
+
# @param association_options [Hash] Non-default options to write; nil values are skipped
|
|
92
|
+
def append_association!(str, assoc_type, assoc, association_options)
|
|
112
93
|
str << " #{assoc_type} #{assoc.name.inspect}"
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
str << ", #{name}: '#{value}'"
|
|
116
|
-
end
|
|
94
|
+
association_options.compact.each do |name, value|
|
|
95
|
+
str << ", #{name}: '#{value}'"
|
|
117
96
|
end
|
|
118
97
|
str << "\n"
|
|
119
98
|
end
|
|
@@ -166,7 +145,7 @@ module DynamicActiveModel
|
|
|
166
145
|
def has_and_belongs_to_many_association_options(assoc)
|
|
167
146
|
options = {}
|
|
168
147
|
options[:join_table] = assoc.options[:join_table] if assoc.options[:join_table]
|
|
169
|
-
unless assoc.options[:class_name].underscore.
|
|
148
|
+
unless assoc.options[:class_name].underscore.pluralize == assoc.name.to_s
|
|
170
149
|
options[:class_name] =
|
|
171
150
|
assoc.options[:class_name]
|
|
172
151
|
end
|
|
@@ -178,19 +157,5 @@ module DynamicActiveModel
|
|
|
178
157
|
def default_foreign_key_name
|
|
179
158
|
"#{@model.table_name.underscore.singularize}_id"
|
|
180
159
|
end
|
|
181
|
-
|
|
182
|
-
# Generates the default foreign key for the associated model
|
|
183
|
-
# @param assoc [ActiveRecord::Reflection::HasAndBelongsToManyReflection] The association
|
|
184
|
-
# @return [String] The generated foreign key name
|
|
185
|
-
def generate_association_foreign_key(assoc)
|
|
186
|
-
"#{assoc.options[:class_name].underscore.singularize}_id"
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
# Gets a constant by its fully qualified name
|
|
190
|
-
# @param class_name [String] The fully qualified class name
|
|
191
|
-
# @return [Class] The resolved class
|
|
192
|
-
def const_get(class_name)
|
|
193
|
-
class_name.split('::').inject(Object) { |mod, name| mod.const_get(name) }
|
|
194
|
-
end
|
|
195
160
|
end
|
|
196
161
|
end
|