active_record-mti 0.3.2 → 0.4.0.pre.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -6
  3. data/{LICENSE.txt → LICENSE} +0 -0
  4. data/README.md +47 -10
  5. data/lib/active_record/mti.rb +56 -56
  6. data/lib/active_record/mti/config.rb +26 -0
  7. data/lib/active_record/mti/connection_adapters/postgresql/adapter.rb +0 -8
  8. data/lib/active_record/mti/connection_adapters/postgresql/schema_statements.rb +30 -11
  9. data/lib/active_record/mti/core_extension.rb +170 -0
  10. data/lib/active_record/mti/railtie.rb +9 -4
  11. data/lib/active_record/mti/relation.rb +95 -0
  12. data/lib/active_record/mti/schema_dumper.rb +4 -4
  13. data/lib/active_record/mti/table.rb +19 -0
  14. data/lib/active_record/mti/table_oid.rb +6 -0
  15. data/lib/active_record/mti/version.rb +1 -1
  16. data/lib/core_ext/array.rb +14 -0
  17. data/lib/core_ext/hash.rb +1 -3
  18. data/lib/core_ext/thread.rb +14 -0
  19. metadata +94 -95
  20. data/.gitignore +0 -78
  21. data/.rspec +0 -2
  22. data/.travis.yml +0 -38
  23. data/Gemfile +0 -21
  24. data/Rakefile +0 -6
  25. data/active_record-mti.gemspec +0 -42
  26. data/gemfiles/activerecord-4.0.Gemfile +0 -3
  27. data/gemfiles/activerecord-4.1.Gemfile +0 -3
  28. data/gemfiles/activerecord-4.2.Gemfile +0 -3
  29. data/gemfiles/activerecord-5.0.Gemfile +0 -3
  30. data/gemfiles/activerecord-5.1.Gemfile +0 -3
  31. data/lib/active_record/mti/calculations.rb +0 -23
  32. data/lib/active_record/mti/inheritance.rb +0 -127
  33. data/lib/active_record/mti/model_schema.rb +0 -55
  34. data/lib/active_record/mti/query_methods.rb +0 -40
  35. data/lib/active_record/mti/querying.rb +0 -7
  36. data/lib/active_record/mti/registry.rb +0 -23
  37. data/spec/active_record/mti/calculations_spec.rb +0 -56
  38. data/spec/active_record/mti/inheritance_spec.rb +0 -184
  39. data/spec/active_record/mti/model_schema_spec.rb +0 -11
  40. data/spec/active_record/mti/query_methods_spec.rb +0 -12
  41. data/spec/active_record/mti/schema_dumper_spec.rb +0 -22
  42. data/spec/active_record/mti_spec.rb +0 -24
  43. data/spec/active_record/sti/inheritance_spec.rb +0 -24
  44. data/spec/spec_helper.rb +0 -28
  45. data/spec/support/rails/app/models/admin.rb +0 -3
  46. data/spec/support/rails/app/models/comment.rb +0 -4
  47. data/spec/support/rails/app/models/post.rb +0 -4
  48. data/spec/support/rails/app/models/transportation/military/vehicle.rb +0 -7
  49. data/spec/support/rails/app/models/transportation/truck.rb +0 -5
  50. data/spec/support/rails/app/models/transportation/vehicle.rb +0 -4
  51. data/spec/support/rails/app/models/user.rb +0 -6
  52. data/spec/support/rails/config/database.yml +0 -4
  53. data/spec/support/rails/config/routes.rb +0 -3
  54. data/spec/support/rails/db/schema.rb +0 -51
  55. data/spec/support/rails/log/.gitignore +0 -1
  56. data/spec/support/rails/public/favicon.ico +0 -0
@@ -1,7 +0,0 @@
1
- module ActiveRecord
2
- module MTI
3
- module Querying
4
- delegate :count_estimate, to: :all
5
- end
6
- end
7
- end
@@ -1,23 +0,0 @@
1
- module ActiveRecord
2
- module MTI
3
- module Registry
4
-
5
- mattr_accessor :tableoids
6
- self.tableoids = { ActiveRecord::Base => false }
7
-
8
- def self.[]=(klass, tableoid)
9
- ActiveRecord::MTI.logger.debug "Adding #{klass} to MTI list with #{tableoid}"
10
- tableoids[klass] = tableoid
11
- end
12
-
13
- def self.find_mti_class(tableoid)
14
- tableoids.key(tableoid)
15
- end
16
-
17
- def self.tableoid?(klass)
18
- tableoids[klass]
19
- end
20
-
21
- end
22
- end
23
- end
@@ -1,56 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveRecord::MTI::Calculations do
4
-
5
- context 'when an exception occurs' do
6
- it 'does not continue to adversely affect additional queries' do
7
- Admin.create(email: 'bob')
8
- expect{ Admin.joins(Transportation::Vehicle).count }.to raise_error(RuntimeError)
9
- expect(Thread.current['skip_tableoid_cast']).to_not eq(true)
10
- expect(Admin.count).to eq(1)
11
- end
12
- end
13
-
14
- context "don't project tableoid on" do
15
- it "grouping" do
16
-
17
- Admin.create(email: 'foo@bar.baz', god_powers: 3)
18
- Admin.create(email: 'foo@bar.baz', god_powers: 3)
19
- Admin.create(email: 'foo24@bar.baz', god_powers: 3)
20
-
21
- grouped_count = Admin.group(:email).count
22
-
23
- expect(grouped_count['foo24@bar.baz']).to eq(1)
24
- expect(grouped_count['foo@bar.baz']).to eq(2)
25
-
26
- end
27
-
28
- it "count calculations" do
29
-
30
- Admin.create(email: 'foo@bar.baz', god_powers: 3)
31
- Admin.create(email: 'foo@bar.baz', god_powers: 3)
32
- Admin.create(email: 'foo24@bar.baz', god_powers: 3)
33
-
34
- expect(Admin.count(:email)).to eq(3)
35
-
36
- end
37
- end
38
-
39
- context "projects tableoid" do
40
- it "and groups tableoid when selecting :tableoid" do
41
- sql = Admin.select(:email, :tableoid).group(:email).to_sql
42
-
43
- expect(sql).to match(/SELECT .*, \"admins\".\"tableoid\" AS tableoid FROM \"admins\"/)
44
-
45
- expect(sql).to match(/GROUP BY .*, \"admins\".\"tableoid\"/)
46
- end
47
-
48
- it "when grouping :tableoid" do
49
- sql = Admin.select(:email).group(:email, :tableoid).to_sql
50
-
51
- expect(sql).to match(/SELECT .*, \"admins\".\"tableoid\" AS tableoid FROM \"admins\"/)
52
-
53
- expect(sql).to match(/GROUP BY .*, \"admins\".\"tableoid\"/)
54
- end
55
- end
56
- end
@@ -1,184 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveRecord::MTI::Inheritance do
4
-
5
- it "creates a column even if class doesn't respond to :attribute" do
6
- allow(Admin).to receive(:respond_to?).with(:attribute).and_return(false)
7
-
8
- ActiveRecord::MTI::Registry.tableoids[Admin] = nil
9
-
10
- expect(Admin.using_multi_table_inheritance?).to eq(true)
11
- end
12
-
13
- it "warns of deprication when using old `uses_mti`" do
14
- expect { Admin.uses_mti }.to output("DEPRECATED - `uses_mti` is no longer needed (nor has any effect)\n").to_stderr
15
- end
16
-
17
- context 'class definition' do
18
-
19
- describe 'for classes that use MTI' do
20
-
21
- it 'has non-nil mti_type_column' do
22
- expect(Admin.mti_type_column).to_not be_nil
23
- end
24
-
25
- it 'has true tableoid_column' do
26
- expect(Admin.tableoid_column).to eq(true)
27
- end
28
-
29
- it "doesn't check inheritance multiple times" do
30
- # Due to the anonymous class ("god = Class.new(Admin)") rspec can't properly distinquish
31
- # between the two classes. So at most 2 times!
32
- expect(Admin).to receive(:check_inheritance_of).and_call_original.at_most(2).times
33
-
34
- Admin.create(email: 'foo@bar.baz', god_powers: 3)
35
- Admin.create(email: 'foo2@bar.baz', god_powers: 3)
36
- Admin.create(email: 'foo24@bar.baz', god_powers: 3)
37
- Admin.create(email: 'foo246@bar.baz', god_powers: 3)
38
-
39
- end
40
- end
41
-
42
- describe "for classes that don't use MTI" do
43
-
44
- it 'has nil tableoid_column' do
45
- expect(Post.tableoid_column).to be_nil
46
- end
47
-
48
- it 'has nil mti_type_column' do
49
- expect(Post.mti_type_column).to be_nil
50
- end
51
-
52
- it "doesn't check inheritance multiple times" do
53
- # ActiveRecord::MTI::Inheritance.register(Post, false)
54
- expect(Post).to receive(:check_inheritance_of).and_call_original.exactly(1).times
55
-
56
- Post.create(title: 'foo@bar.baz')
57
- Post.create(title: 'foo2@bar.baz')
58
- Post.create(title: 'foo24@bar.baz')
59
-
60
- end
61
- end
62
-
63
- end
64
-
65
- context 'default inheritance_column model' do
66
- let!(:user) { User.create(email: 'foo@bar.baz') }
67
- let!(:admin) { Admin.create(email: 'foo@bar.baz', god_powers: 3) }
68
-
69
- it 'casts properly' do
70
- user = User.first
71
- expect(user.class).to eq(User)
72
- end
73
-
74
- describe 'base class querying' do
75
- it 'casts children properly' do
76
- users = User.all
77
- expect(users.select{ |u| u.is_a?(Admin) }.count).to eql(1)
78
- end
79
-
80
- xit 'deserializes children with child specific data' do
81
- my_admin = User.find(admin.id)
82
- expect(my_admin.god_powers).to eql(3)
83
- end
84
- end
85
-
86
- describe 'has the correct count for' do
87
- it 'parents' do
88
- users = User.all
89
- expect(users.count).to eq(2)
90
- end
91
-
92
- it 'children' do
93
- admins = Admin.all
94
- expect(admins.count).to eq(1)
95
- end
96
- end
97
-
98
- describe 'dynamic class creation' do
99
- it 'infers the table_name from superclass not base_class' do
100
- god = Class.new(Admin)
101
- expect(god.table_name).to eql(Admin.table_name)
102
- end
103
-
104
- it 'infers the table_name when defined dynamically' do
105
-
106
- class Scrub < ActiveRecord::Base
107
- const_set(:All, Class.new(Scrub) do |klass|
108
- class_eval <<-AAA
109
- self.table_name = 'scrubs/all'
110
- AAA
111
- end)
112
- end
113
-
114
- expect(Scrub::All.table_name).to eq('scrubs/all')
115
- end
116
- end
117
- end
118
-
119
- describe 'views' do
120
- before(:each) do
121
-
122
- User.connection.execute <<-SQL
123
- CREATE OR REPLACE VIEW "users_all"
124
- AS SELECT * FROM "users"
125
- SQL
126
-
127
- class UserView < User
128
- self.table_name = "users_all"
129
- end
130
-
131
- end
132
-
133
- if ActiveRecord::Base.connection.version >= Gem::Version.new('9.4')
134
- it 'allows creation pass-through' do
135
-
136
- UserView.create(email: 'dale@twilightcoders.net')
137
- end
138
- end
139
- end
140
-
141
- describe 'dynamic class creation' do
142
- it 'infers the table_name from superclass not base_class' do
143
- God = Class.new(Admin)
144
- Hacker = Class.new(Admin)
145
-
146
- expect(God.table_name).to eql(Admin.table_name)
147
- expect(Hacker.table_name).to eql('admin/hackers')
148
- end
149
- end
150
-
151
- describe 'custom inheritance_column model' do
152
- let!(:vehicle) { Transportation::Vehicle.create(color: :red) }
153
- let!(:truck) { Transportation::Truck.create(color: :blue, bed_size: 10) }
154
-
155
- describe 'inheritance_column' do
156
- xit 'should set the custom column correctly' do
157
- expect(vehicle.type).to eql('vehicles')
158
- expect(truck.type).to eql('trucks')
159
- end
160
- end
161
-
162
- describe 'base class querying' do
163
- it 'casts children properly' do
164
- expect(Transportation::Vehicle.all.select{ |v| v.is_a?(Transportation::Truck) }.count).to eql(1)
165
- end
166
-
167
- xit 'deserializes children with child specific data' do
168
- my_truck = Transportation::Vehicle.find(truck.id)
169
- expect(my_truck.bed_size).to eql(10)
170
- end
171
- end
172
-
173
- describe 'has the correct count for' do
174
- it 'parents' do
175
- expect(Transportation::Vehicle.count).to eql(2)
176
- end
177
-
178
- it 'children' do
179
- expect(Transportation::Truck.count).to eql(1)
180
- end
181
- end
182
- end
183
-
184
- end
@@ -1,11 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveRecord::MTI::ModelSchema do
4
-
5
- it 'rescues suffix' do
6
- f = ActiveRecord::ModelSchema::ClassMethods
7
- allow_any_instance_of(f).to receive(:full_table_name_suffix).and_raise(NoMethodError)
8
- expect( Admin.full_table_name_suffix ).to eq("")
9
- end
10
-
11
- end
@@ -1,12 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveRecord::MTI::QueryMethods do
4
-
5
- context "queries" do
6
- it "select tableoid" do
7
- sql = Admin.all.to_sql
8
- expect(sql).to match(/SELECT .*, \"admins\".\"tableoid\" AS tableoid FROM \"admins\"/)
9
- end
10
- end
11
-
12
- end
@@ -1,22 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveRecord::MTI::SchemaDumper do
4
-
5
- before(:each) do
6
- ActiveRecord::SchemaMigration.create_table
7
- end
8
-
9
- let(:hacker_sql) {
10
- <<-FOO
11
- create_table "admin/hackers", inherits: 'admins' do |t|
12
- end
13
- FOO
14
- }
15
-
16
- it 'does not dump indexes for child table' do
17
- stream = StringIO.new
18
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
19
-
20
- expect(stream.string).to include(hacker_sql)
21
- end
22
- end
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveRecord::MTI do
4
-
5
- context 'helper' do
6
-
7
- describe '#testify' do
8
- it "returns true for truthy values" do
9
- expect(ActiveRecord::MTI.testify('f')).to eq(false)
10
- end
11
- end
12
-
13
- it "root has the right value" do
14
- expect(ActiveRecord::MTI.root).not_to be_nil
15
- end
16
-
17
- it "recovers if oid class candidate is not constantizable" do
18
- ActiveRecord::MTI.oid_class_candidates.unshift("IDontExist")
19
- expect(ActiveRecord::MTI.find_oid_class).not_to be_nil
20
- end
21
-
22
- end
23
-
24
- end
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveRecord::Inheritance do
4
-
5
- context 'class definition' do
6
-
7
- describe 'for classes that use STI' do
8
- it "doesn't check inheritance multiple times" do
9
-
10
- Transportation::Military::Vehicle.create(color: :red)
11
- Transportation::Military::Vehicle.create(color: :blue)
12
- Transportation::Military::Vehicle.create(color: :green)
13
- Transportation::Military::Vehicle.create(color: :gold)
14
-
15
- vehicle = Transportation::Military::Vehicle.first
16
- expect(vehicle.class.name).to eq('Transportation::Military::Vehicle')
17
- expect(vehicle.color).to eq('red')
18
-
19
- end
20
- end
21
-
22
- end
23
-
24
- end
data/spec/spec_helper.rb DELETED
@@ -1,28 +0,0 @@
1
- ENV['RAILS_ENV'] = 'test'
2
-
3
- require 'database_cleaner'
4
- require 'combustion'
5
-
6
- require 'simplecov'
7
- SimpleCov.start do
8
- add_filter 'spec'
9
- end
10
-
11
- Combustion.path = 'spec/support/rails'
12
- Combustion.initialize! :active_record
13
-
14
- RSpec.configure do |config|
15
- config.order = 'random'
16
-
17
- # Configure the DatabaseCleaner
18
- config.before(:suite) do
19
- DatabaseCleaner.strategy = :transaction
20
- DatabaseCleaner.clean_with(:truncation)
21
- end
22
-
23
- config.around(:each) do |example|
24
- DatabaseCleaner.cleaning do
25
- example.run
26
- end
27
- end
28
- end
@@ -1,3 +0,0 @@
1
- class Admin < User
2
- self.table_name = 'admins'
3
- end
@@ -1,4 +0,0 @@
1
- class Comment < ::ActiveRecord::Base
2
- belongs_to :user
3
- belongs_to :post
4
- end
@@ -1,4 +0,0 @@
1
- class Post < ::ActiveRecord::Base
2
- belongs_to :user
3
- has_many :comments
4
- end
@@ -1,7 +0,0 @@
1
- module Transportation
2
- module Military
3
- class Vehicle < ::Transportation::Vehicle
4
- self.inheritance_column = 'type'
5
- end
6
- end
7
- end
@@ -1,5 +0,0 @@
1
- module Transportation
2
- class Truck < Vehicle
3
- self.table_name = 'vehicles/trucks'
4
- end
5
- end
@@ -1,4 +0,0 @@
1
- module Transportation
2
- class Vehicle < ::ActiveRecord::Base
3
- end
4
- end