active_record-mti 0.3.2 → 0.4.0.pre.1

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