torque-postgresql 1.1.1 → 2.0.1

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.
Files changed (72) hide show
  1. checksums.yaml +5 -5
  2. data/Rakefile +5 -2
  3. data/lib/torque/postgresql.rb +0 -2
  4. data/lib/torque/postgresql/adapter.rb +0 -1
  5. data/lib/torque/postgresql/adapter/database_statements.rb +4 -15
  6. data/lib/torque/postgresql/adapter/schema_creation.rb +13 -23
  7. data/lib/torque/postgresql/adapter/schema_definitions.rb +7 -21
  8. data/lib/torque/postgresql/adapter/schema_dumper.rb +71 -11
  9. data/lib/torque/postgresql/adapter/schema_statements.rb +2 -12
  10. data/lib/torque/postgresql/associations.rb +0 -3
  11. data/lib/torque/postgresql/associations/association_scope.rb +18 -61
  12. data/lib/torque/postgresql/associations/belongs_to_many_association.rb +2 -1
  13. data/lib/torque/postgresql/associations/preloader.rb +0 -24
  14. data/lib/torque/postgresql/associations/preloader/association.rb +13 -9
  15. data/lib/torque/postgresql/auxiliary_statement.rb +12 -17
  16. data/lib/torque/postgresql/coder.rb +1 -2
  17. data/lib/torque/postgresql/config.rb +0 -4
  18. data/lib/torque/postgresql/inheritance.rb +13 -17
  19. data/lib/torque/postgresql/reflection/abstract_reflection.rb +19 -25
  20. data/lib/torque/postgresql/relation.rb +11 -16
  21. data/lib/torque/postgresql/relation/auxiliary_statement.rb +9 -15
  22. data/lib/torque/postgresql/relation/distinct_on.rb +1 -1
  23. data/lib/torque/postgresql/schema_cache.rb +19 -11
  24. data/lib/torque/postgresql/version.rb +1 -1
  25. data/spec/en.yml +19 -0
  26. data/spec/factories/authors.rb +6 -0
  27. data/spec/factories/comments.rb +13 -0
  28. data/spec/factories/posts.rb +6 -0
  29. data/spec/factories/tags.rb +5 -0
  30. data/spec/factories/texts.rb +5 -0
  31. data/spec/factories/users.rb +6 -0
  32. data/spec/factories/videos.rb +5 -0
  33. data/spec/mocks/cache_query.rb +16 -0
  34. data/spec/mocks/create_table.rb +35 -0
  35. data/spec/models/activity.rb +3 -0
  36. data/spec/models/activity_book.rb +4 -0
  37. data/spec/models/activity_post.rb +7 -0
  38. data/spec/models/activity_post/sample.rb +4 -0
  39. data/spec/models/author.rb +4 -0
  40. data/spec/models/author_journalist.rb +4 -0
  41. data/spec/models/comment.rb +3 -0
  42. data/spec/models/course.rb +2 -0
  43. data/spec/models/geometry.rb +2 -0
  44. data/spec/models/guest_comment.rb +4 -0
  45. data/spec/models/post.rb +6 -0
  46. data/spec/models/tag.rb +2 -0
  47. data/spec/models/text.rb +2 -0
  48. data/spec/models/time_keeper.rb +2 -0
  49. data/spec/models/user.rb +8 -0
  50. data/spec/models/video.rb +2 -0
  51. data/spec/schema.rb +141 -0
  52. data/spec/spec_helper.rb +59 -0
  53. data/spec/tests/arel_spec.rb +72 -0
  54. data/spec/tests/auxiliary_statement_spec.rb +593 -0
  55. data/spec/tests/belongs_to_many_spec.rb +240 -0
  56. data/spec/tests/coder_spec.rb +367 -0
  57. data/spec/tests/collector_spec.rb +59 -0
  58. data/spec/tests/distinct_on_spec.rb +65 -0
  59. data/spec/tests/enum_set_spec.rb +306 -0
  60. data/spec/tests/enum_spec.rb +628 -0
  61. data/spec/tests/geometric_builder_spec.rb +221 -0
  62. data/spec/tests/has_many_spec.rb +390 -0
  63. data/spec/tests/interval_spec.rb +167 -0
  64. data/spec/tests/lazy_spec.rb +24 -0
  65. data/spec/tests/period_spec.rb +954 -0
  66. data/spec/tests/quoting_spec.rb +24 -0
  67. data/spec/tests/range_spec.rb +36 -0
  68. data/spec/tests/relation_spec.rb +57 -0
  69. data/spec/tests/table_inheritance_spec.rb +416 -0
  70. metadata +103 -16
  71. data/lib/torque/postgresql/associations/join_dependency/join_association.rb +0 -15
  72. data/lib/torque/postgresql/schema_dumper.rb +0 -88
@@ -33,7 +33,8 @@ module Torque
33
33
 
34
34
  def ids_writer(new_ids)
35
35
  column = reflection.active_record_primary_key
36
- owner.update_column(column, owner[column] = new_ids.presence)
36
+ command = owner.persisted? ? :update_column : :write_attribute
37
+ owner.public_send(command, column, new_ids.presence)
37
38
  @association_scope = nil
38
39
  end
39
40
 
@@ -1,25 +1 @@
1
1
  require_relative 'preloader/association'
2
-
3
- unless Torque::PostgreSQL::AR521
4
- module Torque
5
- module PostgreSQL
6
- module Associations
7
- module Preloader
8
- BelongsToMany = Class.new(::ActiveRecord::Associations::Preloader::HasMany)
9
-
10
- def preloader_for(reflection, owners, *)
11
- return AlreadyLoaded \
12
- if owners.first.association(reflection.name).loaded?
13
-
14
- return BelongsToMany \
15
- if reflection.macro.eql?(:belongs_to_many)
16
-
17
- super
18
- end
19
- end
20
-
21
- ::ActiveRecord::Associations::Preloader.prepend(Preloader)
22
- end
23
- end
24
- end
25
- end
@@ -8,7 +8,7 @@ module Torque
8
8
 
9
9
  # For reflections connected through an array, make sure to properly
10
10
  # decuple the list of ids and set them as associated with the owner
11
- def run(preloader)
11
+ def run
12
12
  return super unless connected_through_array?
13
13
  send("run_array_for_#{@reflection.macro}")
14
14
  end
@@ -18,7 +18,7 @@ module Torque
18
18
  # Specific run for belongs_many association
19
19
  def run_array_for_belongs_to_many
20
20
  # Add reverse to has_many
21
- records = load_records
21
+ records = groupped_records
22
22
  owners.each do |owner|
23
23
  items = records.values_at(*Array.wrap(owner[owner_key_name]))
24
24
  associate_records_to_owner(owner, items.flatten)
@@ -29,7 +29,7 @@ module Torque
29
29
  def run_array_for_has_many
30
30
  # Add reverse to belongs_to_many
31
31
  records = Hash.new { |h, k| h[k] = [] }
32
- load_records.each do |ids, record|
32
+ groupped_records.each do |ids, record|
33
33
  ids.each { |id| records[id].concat(Array.wrap(record)) }
34
34
  end
35
35
 
@@ -47,14 +47,18 @@ module Torque
47
47
  scope.where(condition).load(&block)
48
48
  end
49
49
 
50
- unless Torque::PostgreSQL::AR521
51
- def associate_records_to_owner(owner, records)
52
- association = owner.association(reflection.name)
53
- association.loaded!
54
- association.target.concat(records)
55
- end
50
+ def associate_records_to_owner(owner, records)
51
+ return super unless connected_through_array?
52
+ association = owner.association(reflection.name)
53
+ association.loaded!
54
+ association.target.concat(records)
56
55
  end
57
56
 
57
+ def groupped_records
58
+ preloaded_records.group_by do |record|
59
+ convert_key(record[association_key_name])
60
+ end
61
+ end
58
62
  end
59
63
 
60
64
  ::ActiveRecord::Associations::Preloader::Association.prepend(Association)
@@ -31,11 +31,12 @@ module Torque
31
31
  end
32
32
 
33
33
  # Fast access to statement build
34
- def build(statement, base, options = nil, bound_attributes = [])
34
+ def build(statement, base, options = nil, bound_attributes = [], join_sources = [])
35
35
  klass = instantiate(statement, base, options)
36
36
  result = klass.build(base)
37
37
 
38
38
  bound_attributes.concat(klass.bound_attributes)
39
+ join_sources.concat(klass.join_sources)
39
40
  result
40
41
  end
41
42
 
@@ -105,7 +106,7 @@ module Torque
105
106
  delegate :config, :table, :table_name, :relation, :configure, :relation_query?,
106
107
  to: :class
107
108
 
108
- attr_reader :bound_attributes
109
+ attr_reader :bound_attributes, :join_sources
109
110
 
110
111
  # Start a new auxiliary statement giving extra options
111
112
  def initialize(*args)
@@ -117,15 +118,21 @@ module Torque
117
118
  @where = options.fetch(:where, {})
118
119
  @select = options.fetch(:select, {})
119
120
  @join_type = options.fetch(:join_type, nil)
121
+
120
122
  @bound_attributes = []
123
+ @join_sources = []
121
124
  end
122
125
 
123
126
  # Build the statement on the given arel and return the WITH statement
124
127
  def build(base)
128
+ @bound_attributes.clear
129
+ @join_sources.clear
130
+
131
+ # Prepare all the data for the statement
125
132
  prepare(base)
126
133
 
127
134
  # Add the join condition to the list
128
- base.joins_values += [build_join(base)]
135
+ @join_sources << build_join(base)
129
136
 
130
137
  # Return the statement with its dependencies
131
138
  [@dependencies, ::Arel::Nodes::As.new(table, build_query(base))]
@@ -204,19 +211,7 @@ module Torque
204
211
  foreign_table = ::Arel::Table.new(association.plural_name)
205
212
  end
206
213
 
207
- # Add the scopes defined by the reflection
208
- # Possibilities:
209
- # table
210
- # table, foreign_klass
211
- # table, foreign_table, foreign_klass
212
- if association.respond_to?(:join_scope)
213
- arity = association.method(:join_scope).arity
214
- args = [@query.arel_table, foreign_table, base]
215
- args.delete_at(1) if arity <= 2 # Delete foreign_table
216
- args.delete_at(1) if arity <= 1 # Delete base (foreign_klass)
217
-
218
- @query.merge(association.join_scope(*args))
219
- end
214
+ @query.merge(association.join_scope(@query.arel_table, foreign_table, base))
220
215
 
221
216
  # Add the join constraints
222
217
  constraint = association.build_join_constraint(table, foreign_table)
@@ -288,7 +283,7 @@ module Torque
288
283
  cte.is_a?(dependent_klass)
289
284
  end
290
285
 
291
- AuxiliaryStatement.build(dependent, base, options, bound_attributes)
286
+ AuxiliaryStatement.build(dependent, base, options, bound_attributes, join_sources)
292
287
  end
293
288
  end
294
289
 
@@ -3,8 +3,7 @@ module Torque
3
3
  module Coder
4
4
 
5
5
  # This class represents an Record to be encoded, instead of a literal Array
6
- class Record < Array
7
- end
6
+ Record = Class.new(Array)
8
7
 
9
8
  class << self
10
9
 
@@ -2,10 +2,6 @@ module Torque
2
2
  module PostgreSQL
3
3
  include ActiveSupport::Configurable
4
4
 
5
- # Stores a version check for compatibility purposes
6
- AR521 = (ActiveRecord.gem_version >= Gem::Version.new('5.2.1'))
7
- AR523 = (ActiveRecord.gem_version >= Gem::Version.new('5.2.3'))
8
-
9
5
  # Use the same logger as the Active Record one
10
6
  def self.logger
11
7
  ActiveRecord::Base.logger
@@ -18,14 +18,7 @@ module Torque
18
18
  klass.find(self.id)
19
19
  end
20
20
 
21
- private
22
-
23
- def using_single_table_inheritance?(record) # :nodoc:
24
- self.class.physically_inherited? || super
25
- end
26
-
27
21
  module ClassMethods
28
-
29
22
  delegate :_auto_cast_attribute, :_record_class_attribute, to: ActiveRecord::Relation
30
23
 
31
24
  # Get a full list of all attributes from a model and all its dependents
@@ -101,9 +94,10 @@ module Torque
101
94
 
102
95
  # Get the final decorated table, regardless of any special condition
103
96
  def decorated_table_name
104
- if parent < Base && !parent.abstract_class?
105
- contained = parent.table_name
106
- contained = contained.singularize if parent.pluralize_table_names
97
+ parent_class = try(:module_parent) || try(:parent)
98
+ if parent_class < Base && !parent_class.abstract_class?
99
+ contained = parent_class.table_name
100
+ contained = contained.singularize if parent_class.pluralize_table_names
107
101
  contained += "_"
108
102
  end
109
103
 
@@ -144,17 +138,19 @@ module Torque
144
138
 
145
139
  private
146
140
 
147
- def discriminate_class_for_record(record) # :nodoc:
141
+ def instantiate_instance_of(klass, attributes, column_types = {}, &block)
142
+ return super unless klass.physically_inheritances?
143
+
148
144
  auto_cast = _auto_cast_attribute.to_s
149
145
  record_class = _record_class_attribute.to_s
146
+ return super unless attributes.key?(record_class) &&
147
+ attributes.delete(auto_cast) && attributes[record_class] != table_name
150
148
 
151
- return super unless record.key?(record_class) &&
152
- record.delete(auto_cast) && record[record_class] != table_name
149
+ klass = casted_dependents[attributes[record_class]]
150
+ raise_unable_to_cast(attributes[record_class]) if klass.nil?
151
+ filter_attributes_for_cast(attributes, klass)
153
152
 
154
- klass = casted_dependents[record[record_class]]
155
- raise_unable_to_cast(record[record_class]) if klass.nil?
156
- filter_attributes_for_cast(record, klass)
157
- klass
153
+ super(klass, attributes, column_types, &block)
158
154
  end
159
155
 
160
156
  # Filter the record attributes to be loaded to not included those from
@@ -12,28 +12,21 @@ module Torque
12
12
  false
13
13
  end
14
14
 
15
- # Monkey patching for rais 5.0
16
- def torque_join_keys
17
- method(:join_keys).arity.eql?(0) ? join_keys : join_keys(klass)
18
- end
19
-
20
- # Fix for rails 5.2.3 where the join_scope method is the one now
21
- # responsible for building the join condition
22
- if Torque::PostgreSQL::AR523
23
- def join_scope(table, foreign_table, foreign_klass)
24
- return super unless connected_through_array?
25
-
26
- predicate_builder = predicate_builder(table)
27
- scope_chain_items = join_scopes(table, predicate_builder)
28
- klass_scope = klass_join_scope(table, predicate_builder)
29
-
30
- klass_scope.where!(build_id_constraint_between(table, foreign_table))
31
- klass_scope.where!(type => foreign_klass.polymorphic_name) if type
32
- klass_scope.where!(klass.send(:type_condition, table)) \
33
- if klass.finder_needs_type_condition?
15
+ # Fix where the join_scope method is the one now responsible for
16
+ # building the join condition
17
+ def join_scope(table, foreign_table, foreign_klass)
18
+ return super unless connected_through_array?
19
+
20
+ predicate_builder = predicate_builder(table)
21
+ scope_chain_items = join_scopes(table, predicate_builder)
22
+ klass_scope = klass_join_scope(table, predicate_builder)
23
+
24
+ klass_scope.where!(build_id_constraint_between(table, foreign_table))
25
+ klass_scope.where!(type => foreign_klass.polymorphic_name) if type
26
+ klass_scope.where!(klass.send(:type_condition, table)) \
27
+ if klass.finder_needs_type_condition?
34
28
 
35
- scope_chain_items.inject(klass_scope, &:merge!)
36
- end
29
+ scope_chain_items.inject(klass_scope, &:merge!)
37
30
  end
38
31
 
39
32
  # Manually build the join constraint
@@ -50,9 +43,9 @@ module Torque
50
43
  return klass_attr.eq(source_attr) unless connected_through_array?
51
44
 
52
45
  # Klass and key are associated with the reflection Class
53
- klass_type = klass.columns_hash[torque_join_keys.key.to_s]
46
+ klass_type = klass.columns_hash[join_keys.key.to_s]
54
47
  # active_record and foreign_key are associated with the source Class
55
- source_type = active_record.columns_hash[torque_join_keys.foreign_key.to_s]
48
+ source_type = active_record.columns_hash[join_keys.foreign_key.to_s]
56
49
 
57
50
  # If both are attributes but the left side is not an array, and the
58
51
  # right side is, use the ANY operation
@@ -78,8 +71,8 @@ module Torque
78
71
  private
79
72
 
80
73
  def build_id_constraint_between(table, foreign_table)
81
- klass_attr = table[torque_join_keys.key.to_s]
82
- source_attr = foreign_table[torque_join_keys.foreign_key.to_s]
74
+ klass_attr = table[join_keys.key.to_s]
75
+ source_attr = foreign_table[join_keys.foreign_key.to_s]
83
76
 
84
77
  build_id_constraint(klass_attr, source_attr)
85
78
  end
@@ -105,6 +98,7 @@ module Torque
105
98
  # returns either +nil+ or the inverse association name that it finds.
106
99
  def automatic_inverse_of
107
100
  return super unless connected_through_array?
101
+
108
102
  if can_find_inverse_of_automatically?(self)
109
103
  inverse_name = options[:as] || active_record.name.demodulize
110
104
  inverse_name = ActiveSupport::Inflector.underscore(inverse_name)
@@ -52,11 +52,8 @@ module Torque
52
52
  when Array
53
53
  resolve_column(item, base)
54
54
  when Hash
55
- raise ArgumentError, "Unsupported Hash for attributes on third level" if base
56
- item.map do |key, other_list|
57
- other_list = [other_list] unless other_list.kind_of? Enumerable
58
- resolve_column(other_list, key)
59
- end
55
+ raise ArgumentError, 'Unsupported Hash for attributes on third level' if base
56
+ item.map { |key, other_list| resolve_column(Array.wrap(other_list), key) }
60
57
  else
61
58
  raise ArgumentError, "Unsupported argument type: #{value} (#{value.class})"
62
59
  end
@@ -138,19 +135,17 @@ module Torque
138
135
  ActiveRecord::Relation::SINGLE_VALUE_METHODS += Relation::SINGLE_VALUE_METHODS
139
136
  ActiveRecord::Relation::MULTI_VALUE_METHODS += Relation::MULTI_VALUE_METHODS
140
137
  ActiveRecord::Relation::VALUE_METHODS += Relation::VALUE_METHODS
141
- ActiveRecord::QueryMethods::VALID_UNSCOPING_VALUES += [:cast_records, :itself_only,
142
- :distinct_on, :auxiliary_statements]
138
+ ActiveRecord::QueryMethods::VALID_UNSCOPING_VALUES += %i[cast_records itself_only
139
+ distinct_on auxiliary_statements]
143
140
 
144
- if ActiveRecord::QueryMethods.const_defined?('DEFAULT_VALUES')
145
- Relation::SINGLE_VALUE_METHODS.each do |value|
146
- ActiveRecord::QueryMethods::DEFAULT_VALUES[value] = nil \
147
- if ActiveRecord::QueryMethods::DEFAULT_VALUES[value].nil?
148
- end
141
+ Relation::SINGLE_VALUE_METHODS.each do |value|
142
+ ActiveRecord::QueryMethods::DEFAULT_VALUES[value] = nil \
143
+ if ActiveRecord::QueryMethods::DEFAULT_VALUES[value].nil?
144
+ end
149
145
 
150
- Relation::MULTI_VALUE_METHODS.each do |value|
151
- ActiveRecord::QueryMethods::DEFAULT_VALUES[value] ||= \
152
- ActiveRecord::QueryMethods::FROZEN_EMPTY_ARRAY
153
- end
146
+ Relation::MULTI_VALUE_METHODS.each do |value|
147
+ ActiveRecord::QueryMethods::DEFAULT_VALUES[value] ||= \
148
+ ActiveRecord::QueryMethods::FROZEN_EMPTY_ARRAY
154
149
  end
155
150
 
156
151
  $VERBOSE = warn_level
@@ -33,30 +33,24 @@ module Torque
33
33
  # Get all auxiliary statements bound attributes and the base bound
34
34
  # attributes as well
35
35
  def bound_attributes
36
- if Torque::PostgreSQL::AR521
37
- visitor = ::Arel::Visitors::PostgreSQL.new(ActiveRecord::Base.connection)
38
- visitor.accept(self.arel.ast, ::Arel::Collectors::Bind.new).value
39
- else
40
- return super unless self.auxiliary_statements_values.present?
41
- bindings = self.auxiliary_statements_values.map(&:bound_attributes)
42
- (bindings + super).flatten
43
- end
36
+ visitor = ::Arel::Visitors::PostgreSQL.new(ActiveRecord::Base.connection)
37
+ visitor.accept(self.arel.ast, ::Arel::Collectors::Bind.new).value
44
38
  end
45
39
 
46
40
  private
47
41
 
48
42
  # Hook arel build to add the distinct on clause
49
43
  def build_arel(*)
50
- subqueries = build_auxiliary_statements
51
- return super if subqueries.nil?
52
- super.with(subqueries)
44
+ arel = super
45
+ subqueries = build_auxiliary_statements(arel)
46
+ subqueries.nil? ? arel : arel.with(subqueries)
53
47
  end
54
48
 
55
49
  # Build all necessary data for auxiliary statements
56
- def build_auxiliary_statements
57
- return unless self.auxiliary_statements_values.present?
58
- self.auxiliary_statements_values.map do |klass|
59
- klass.build(self)
50
+ def build_auxiliary_statements(arel)
51
+ return unless auxiliary_statements_values.present?
52
+ auxiliary_statements_values.map do |klass|
53
+ klass.build(self).tap { arel.join_sources.concat(klass.join_sources) }
60
54
  end
61
55
  end
62
56
 
@@ -33,7 +33,7 @@ module Torque
33
33
 
34
34
  # Hook arel build to add the distinct on clause
35
35
  def build_arel(*)
36
- arel = Torque::PostgreSQL::AR521 ? super : super()
36
+ arel = super
37
37
  value = self.distinct_on_values
38
38
  arel.distinct_on(resolve_column(value)) if value.present?
39
39
  arel
@@ -11,6 +11,7 @@ module Torque
11
11
  @data_sources_model_names = {}
12
12
  @inheritance_dependencies = {}
13
13
  @inheritance_associations = {}
14
+ @inheritance_loaded = false
14
15
  end
15
16
 
16
17
  def initialize_dup(*) # :nodoc:
@@ -22,16 +23,16 @@ module Torque
22
23
 
23
24
  def encode_with(coder) # :nodoc:
24
25
  super
25
- coder["data_sources_model_names"] = @data_sources_model_names
26
- coder["inheritance_dependencies"] = @inheritance_dependencies
27
- coder["inheritance_associations"] = @inheritance_associations
26
+ coder['data_sources_model_names'] = @data_sources_model_names
27
+ coder['inheritance_dependencies'] = @inheritance_dependencies
28
+ coder['inheritance_associations'] = @inheritance_associations
28
29
  end
29
30
 
30
31
  def init_with(coder) # :nodoc:
31
32
  super
32
- @data_sources_model_names = coder["data_sources_model_names"]
33
- @inheritance_dependencies = coder["inheritance_dependencies"]
34
- @inheritance_associations = coder["inheritance_associations"]
33
+ @data_sources_model_names = coder['data_sources_model_names']
34
+ @inheritance_dependencies = coder['inheritance_dependencies']
35
+ @inheritance_associations = coder['inheritance_associations']
35
36
  end
36
37
 
37
38
  def add(table_name, *) # :nodoc:
@@ -41,6 +42,7 @@ module Torque
41
42
  if @data_sources.key?(table_name)
42
43
  @inheritance_dependencies.clear
43
44
  @inheritance_associations.clear
45
+ @inheritance_loaded = false
44
46
  end
45
47
  end
46
48
 
@@ -49,6 +51,7 @@ module Torque
49
51
  @data_sources_model_names.clear
50
52
  @inheritance_dependencies.clear
51
53
  @inheritance_associations.clear
54
+ @inheritance_loaded = false
52
55
  end
53
56
 
54
57
  def size # :nodoc:
@@ -71,10 +74,12 @@ module Torque
71
74
  @inheritance_dependencies,
72
75
  @inheritance_associations,
73
76
  @data_sources_model_names,
77
+ @inheritance_loaded,
74
78
  ]
75
79
  end
76
80
 
77
81
  def marshal_load(array) # :nodoc:
82
+ @inheritance_loaded = array.pop
78
83
  @data_sources_model_names = array.pop
79
84
  @inheritance_associations = array.pop
80
85
  @inheritance_dependencies = array.pop
@@ -101,13 +106,13 @@ module Torque
101
106
  end
102
107
 
103
108
  # Try to find a model based on a given table
104
- def lookup_model(table_name, scopred_class = '')
105
- scopred_class = scopred_class.name if scopred_class.is_a?(Class)
109
+ def lookup_model(table_name, scoped_class = '')
110
+ scoped_class = scoped_class.name if scoped_class.is_a?(Class)
106
111
  return @data_sources_model_names[table_name] \
107
112
  if @data_sources_model_names.key?(table_name)
108
113
 
109
114
  # Get all the possible scopes
110
- scopes = scopred_class.scan(/(?:::)?[A-Z][a-z]+/)
115
+ scopes = scoped_class.scan(/(?:::)?[A-Z][a-z]+/)
111
116
  scopes.unshift('Object::')
112
117
 
113
118
  # Consider the maximum namespaced possible model name
@@ -164,14 +169,17 @@ module Torque
164
169
  # Reload information about tables inheritance and dependencies, uses a
165
170
  # cache to not perform additional checkes
166
171
  def reload_inheritance_data!
167
- return if @inheritance_dependencies.present?
172
+ return if @inheritance_loaded
168
173
  @inheritance_dependencies = connection.inherited_tables
169
174
  @inheritance_associations = generate_associations
175
+ @inheritance_loaded = true
170
176
  end
171
177
 
172
178
  # Calculates the inverted dependency (association), where even indirect
173
179
  # inheritance comes up in the list
174
180
  def generate_associations
181
+ return {} if @inheritance_dependencies.empty?
182
+
175
183
  result = Hash.new{ |h, k| h[k] = [] }
176
184
  masters = @inheritance_dependencies.values.flatten.uniq
177
185
 
@@ -200,7 +208,7 @@ module Torque
200
208
  super
201
209
  @data_sources_model_names = Torque::PostgreSQL.config
202
210
  .irregular_models.slice(*@data_sources.keys).map do |table_name, model_name|
203
- [table_name, model_name.constantize]
211
+ [table_name, (model_name.is_a?(Class) ? model_name : model_name.constantize)]
204
212
  end.to_h
205
213
  end
206
214