active_record-mti 0.1.1 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cf67d3c346558b94eeaf4b68d354e4f29bcaa0b4
4
- data.tar.gz: 29beb0dfeb868e4333add080161327582940ecf0
3
+ metadata.gz: 83f66dc4e6bb45b2ca6a075be93334d2f9e761f3
4
+ data.tar.gz: 4e4f3ec52bf515e9d9ffdfaab67306b480bbbdd1
5
5
  SHA512:
6
- metadata.gz: ad4df7d52b11712e43a283d2e9008c7611f8bc7b96ae1545693e04a002fe694e38f7959b7f04f9fcf4aea76a0e9f8dfb110389b6fa6252ee001b636878706673
7
- data.tar.gz: 5ea3c7c73e457bc10f16c69cc4b2a1f53b02f8c904e5cf7ccefb58ec568f4de6079bf2cebd1d512f62ad3940dc0129700ee0901e6e0040274f8356e91ba2f43e
6
+ metadata.gz: 0d08825e3d3f51e944963bcf9cf64cf27c16a9b3319fe2ccd50022d26ece1f608cae5f23d6ea8576b2fc98c4859726e72ee39a544aad33d8ebf38b4621528efc
7
+ data.tar.gz: babb8e13a0371b408f3670059bb5482c4db455dd881c801c4ef1f62ddec542b36d79e0592a5e067a203cc3b2ee7b02e7fe9856bef3a0cc8aee1b1752f22cf696
data/README.md CHANGED
@@ -1,4 +1,9 @@
1
- # ActiveRecord::MTI [![Build Status](https://travis-ci.org/TwilightCoders/active_record-mti.svg?branch=master)](https://travis-ci.org/TwilightCoders/active_record-mti) [![Code Climate](https://codeclimate.com/github/TwilightCoders/active_record-mti/badges/gpa.svg)](https://codeclimate.com/github/TwilightCoders/active_record-mti) [![Test Coverage](https://codeclimate.com/github/TwilightCoders/active_record-mti/badges/coverage.svg)](https://codeclimate.com/github/TwilightCoders/active_record-mti/coverage)
1
+ [![Version ](https://img.shields.io/gem/v/active_record-mti.svg?maxAge=2592000)](https://rubygems.org/gems/active_record-mti)
2
+ [![Build Status ](https://travis-ci.org/TwilightCoders/active_record-mti.svg)](https://travis-ci.org/TwilightCoders/active_record-mti)
3
+ [![Code Climate ](https://codeclimate.com/github/TwilightCoders/active_record-mti/badges/gpa.svg)](https://codeclimate.com/github/TwilightCoders/active_record-mti)
4
+ [![Test Coverage](https://codeclimate.com/github/TwilightCoders/active_record-mti/badges/coverage.svg)](https://codeclimate.com/github/TwilightCoders/active_record-mti/coverage)
5
+
6
+ # ActiveRecord::MTI
2
7
 
3
8
  Allows for true native inheritance of tables in PostgreSQL
4
9
 
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_development_dependency 'bundler', '~> 1.3'
38
38
  spec.add_development_dependency 'rake', '~> 10.0'
39
39
  spec.add_development_dependency 'rspec', '~> 3.0'
40
- spec.add_development_dependency 'simplecov', ['>= 0.9.0', '<1.0.0']
40
+ spec.add_development_dependency 'simplecov', '~> 0.1'
41
41
  spec.add_development_dependency 'codeclimate-test-reporter', '~> 1.0'
42
42
  spec.add_development_dependency 'database_cleaner', '~> 1.6'
43
43
 
@@ -14,6 +14,17 @@ require 'active_record/mti/railtie' if defined?(Rails::Railtie)
14
14
  module ActiveRecord
15
15
  module MTI
16
16
 
17
+ class << self
18
+ attr_writer :logger
19
+
20
+ def logger
21
+ @logger ||= Logger.new($stdout).tap do |log|
22
+ log.progname = self.name
23
+ log.level = Logger::INFO
24
+ end
25
+ end
26
+ end
27
+
17
28
  def self.root
18
29
  @root ||= Pathname.new(File.expand_path('../../', File.dirname(__FILE__)))
19
30
  end
@@ -102,7 +102,7 @@ module ActiveRecord
102
102
 
103
103
  # Remove our cast otherwise PSQL will insist that it be included in the GROUP
104
104
  # Somewhere between line 82 and 101 relation.arel.projections gets reset :/
105
- relation.arel.projections.select!{ |p| p.to_s != tableoid_cast(klass) } if @klass.using_multi_table_inheritance?
105
+ relation.arel.projections.select!{ |p| p != tableoid_cast(klass) } if @klass.using_multi_table_inheritance?
106
106
 
107
107
  query_builder = relation.arel
108
108
  bind_values = query_builder.bind_values + relation.bind_values
@@ -24,6 +24,7 @@ module ActiveRecord
24
24
  module MTI
25
25
  module Inheritance
26
26
  extend ActiveSupport::Concern
27
+ @mti_tableoids = {}
27
28
 
28
29
  included do
29
30
  scope :discern_inheritance, -> {
@@ -37,6 +38,9 @@ module ActiveRecord
37
38
  self.inheritance_column = inheritance_column
38
39
 
39
40
  @uses_mti = true
41
+ @mti_setup = false
42
+ @mti_tableoid_projection = nil
43
+ @tableoid_column = nil
40
44
  end
41
45
 
42
46
  def using_multi_table_inheritance?(klass = self)
@@ -44,15 +48,31 @@ module ActiveRecord
44
48
  end
45
49
 
46
50
  def uses_mti?
47
- @uses_mti = check_inheritence_of(@table_name) if @uses_mti.nil?
51
+ inheritence_check = check_inheritence_of(@table_name) unless @mti_setup
52
+ @uses_mti = inheritence_check if @uses_mti.nil?
48
53
  @uses_mti
49
54
  end
50
55
 
56
+ def has_tableoid_column?
57
+ @tableoid_column != false
58
+ end
59
+
60
+ def mti_tableoid_projection
61
+ @mti_tableoid_projection
62
+ end
63
+
64
+ def mti_tableoid_projection=(value)
65
+ @mti_tableoid_projection = value
66
+ end
67
+
51
68
  private
52
69
 
53
70
  def check_inheritence_of(table_name)
71
+ ActiveRecord::MTI.logger.debug "Trying to check inheritance of table with no table name (#{self})" unless table_name
54
72
  return nil unless table_name
55
73
 
74
+ ActiveRecord::MTI.logger.debug "Checking inheritance for #{table_name}"
75
+
56
76
  result = connection.execute <<-SQL
57
77
  SELECT EXISTS (
58
78
  SELECT 1
@@ -65,10 +85,40 @@ module ActiveRecord
65
85
  );
66
86
  SQL
67
87
 
88
+ uses_inheritence = result.try(:first).try(:values).try(:first) == 't'
89
+
90
+ register_tableoid(table_name, uses_inheritence)
91
+
92
+ @mti_setup = true
68
93
  # Some versions of PSQL return {"?column?"=>"t"}
69
94
  # instead of {"exists"=>"t"}, so we're saying screw it,
70
95
  # just give me the first value of whatever is returned
71
- return result.try(:first).try(:values).try(:first) == 't'
96
+ return uses_inheritence
97
+ end
98
+
99
+ def register_tableoid(table_name, uses_mti=false)
100
+
101
+ tableoid_query = connection.execute(<<-SQL
102
+ SELECT '#{table_name}'::regclass::oid AS tableoid, (SELECT EXISTS (
103
+ SELECT 1
104
+ FROM pg_catalog.pg_attribute
105
+ WHERE attrelid = '#{table_name}'::regclass
106
+ AND attname = 'tableoid'
107
+ AND NOT attisdropped
108
+ )) AS has_tableoid_column
109
+ SQL
110
+ ).first
111
+ tableoid = tableoid_query['tableoid']
112
+ @tableoid_column = tableoid_query['has_tableoid_column'] == 't'
113
+
114
+ if (has_tableoid_column?)
115
+ ActiveRecord::MTI.logger.debug "#{table_name} has tableoid column!"
116
+ @mti_tableoid_projection = arel_table[:tableoid].as('tableoid')
117
+ else
118
+ @mti_tableoid_projection = nil
119
+ end
120
+
121
+ Inheritance.add_mti(tableoid, self)
72
122
  end
73
123
 
74
124
  # Called by +instantiate+ to decide which class to use for a new
@@ -76,7 +126,7 @@ module ActiveRecord
76
126
  # for a +type+ column and return the corresponding class.
77
127
  def discriminate_class_for_record(record)
78
128
  if using_multi_table_inheritance?(base_class)
79
- find_mti_class(record)
129
+ find_mti_class(record) || base_class
80
130
  elsif using_single_table_inheritance?(record)
81
131
  find_sti_class(record[inheritance_column])
82
132
  else
@@ -87,9 +137,11 @@ module ActiveRecord
87
137
  # Search descendants for one who's table_name is equal to the returned tableoid.
88
138
  # This indicates the class of the record
89
139
  def find_mti_class(record)
90
- record['tableoid'].classify.constantize
91
- rescue NameError => e
92
- descendants.find(Proc.new{ self }) { |d| d.table_name == record['tableoid'] }
140
+ if (has_tableoid_column?)
141
+ Inheritance.find_mti(record['tableoid'])
142
+ else
143
+ self
144
+ end
93
145
  end
94
146
 
95
147
  # Type condition only applies if it's STI, otherwise it's
@@ -104,8 +156,16 @@ module ActiveRecord
104
156
  sti_column.in(sti_names)
105
157
  end
106
158
  end
159
+ end
107
160
 
161
+ def self.add_mti(tableoid, klass)
162
+ @mti_tableoids[tableoid.to_s.to_sym] = klass
108
163
  end
164
+
165
+ def self.find_mti(tableoid)
166
+ @mti_tableoids[tableoid.to_s.to_sym]
167
+ end
168
+
109
169
  end
110
170
  end
111
171
  end
@@ -6,8 +6,10 @@ module ActiveRecord
6
6
 
7
7
  # Retrieve the OID as well on a default select
8
8
  def build_select(arel)
9
- arel.project(tableoid_cast(@klass)) if @klass.using_multi_table_inheritance?
10
- # arel.project("\"#{klass.table_name}\".\"tableoid\"::regclass as \"#{klass.inheritance_column}\"") if @klass.using_multi_table_inheritance?
9
+ if @klass.using_multi_table_inheritance? && @klass.has_tableoid_column?
10
+ arel.project(tableoid_cast(@klass))
11
+ end
12
+
11
13
  if select_values.any?
12
14
  arel.project(*arel_columns(select_values.uniq))
13
15
  else
@@ -18,7 +20,7 @@ module ActiveRecord
18
20
  def tableoid_cast(klass)
19
21
  # Arel::Nodes::NamedFunction.new('CAST', [klass.arel_table[:tableoid].as('regclass')])
20
22
  # Arel::Nodes::NamedFunction.new('CAST', [@klass.arel_table['tableoid::regclass'].as('regclass')])
21
- "TRIM(BOTH '\"' FROM CAST(\"#{klass.table_name}\".\"tableoid\"::regclass AS text)) AS tableoid"
23
+ @klass.mti_tableoid_projection
22
24
  end
23
25
 
24
26
  end
@@ -4,7 +4,7 @@ module ActiveRecord
4
4
  module MTI
5
5
  class Railtie < Rails::Railtie
6
6
  initializer 'active_record-mti.load' do |_app|
7
- puts "ActiveRecord::MTI railtie initializer"
7
+ ActiveRecord::MTI.logger.info "ActiveRecord::MTI railtie initializer"
8
8
  ActiveSupport.on_load(:active_record) do
9
9
  ActiveRecord::MTI.load
10
10
  end
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module MTI
3
- VERSION = '0.1.1'
3
+ VERSION = '0.2.1'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record-mti
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dale Stevens
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-23 00:00:00.000000000 Z
11
+ date: 2017-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -104,22 +104,16 @@ dependencies:
104
104
  name: simplecov
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: 0.9.0
110
- - - "<"
107
+ - - "~>"
111
108
  - !ruby/object:Gem::Version
112
- version: 1.0.0
109
+ version: '0.1'
113
110
  type: :development
114
111
  prerelease: false
115
112
  version_requirements: !ruby/object:Gem::Requirement
116
113
  requirements:
117
- - - ">="
118
- - !ruby/object:Gem::Version
119
- version: 0.9.0
120
- - - "<"
114
+ - - "~>"
121
115
  - !ruby/object:Gem::Version
122
- version: 1.0.0
116
+ version: '0.1'
123
117
  - !ruby/object:Gem::Dependency
124
118
  name: codeclimate-test-reporter
125
119
  requirement: !ruby/object:Gem::Requirement