active_record-mti 0.1.1 → 0.2.1

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