torque-postgresql 1.1.1 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
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