updateable_views_inheritance 1.1.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 (61) hide show
  1. data/.gitignore +3 -0
  2. data/Gemfile +4 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +110 -0
  5. data/Rakefile +35 -0
  6. data/doc/template/horo.rb +613 -0
  7. data/lib/generators/updateable_views_inheritance_migration/USAGE +8 -0
  8. data/lib/generators/updateable_views_inheritance_migration/templates/migration.rb +17 -0
  9. data/lib/generators/updateable_views_inheritance_migration/uvi_migration_generator.rb +12 -0
  10. data/lib/updateable_views_inheritance.rb +5 -0
  11. data/lib/updateable_views_inheritance/active_record.rb +16 -0
  12. data/lib/updateable_views_inheritance/postgresql_adapter.rb +450 -0
  13. data/lib/updateable_views_inheritance/version.rb +3 -0
  14. data/tasks/updateable_views_inheritance_tasks.rake +19 -0
  15. data/test/app/models/bicycle.rb +3 -0
  16. data/test/app/models/boat.rb +3 -0
  17. data/test/app/models/car.rb +3 -0
  18. data/test/app/models/electric_locomotive.rb +3 -0
  19. data/test/app/models/electric_train.rb +3 -0
  20. data/test/app/models/locomotive.rb +3 -0
  21. data/test/app/models/maglev_locomotive.rb +3 -0
  22. data/test/app/models/maglev_train.rb +3 -0
  23. data/test/app/models/rack_locomotive.rb +3 -0
  24. data/test/app/models/rack_train.rb +3 -0
  25. data/test/app/models/railed_vehicle.rb +3 -0
  26. data/test/app/models/steam_locomotive.rb +3 -0
  27. data/test/app/models/steam_train.rb +3 -0
  28. data/test/app/models/train.rb +3 -0
  29. data/test/app/models/vehicle.rb +3 -0
  30. data/test/app/models/wheeled_vehicle.rb +3 -0
  31. data/test/config/database.yml +19 -0
  32. data/test/config/environment.rb +14 -0
  33. data/test/config/routes.rb +3 -0
  34. data/test/config/schema.rb +3 -0
  35. data/test/content_test.rb +66 -0
  36. data/test/database.yml +7 -0
  37. data/test/deep_hierarchy_test.rb +64 -0
  38. data/test/fixtures/bicycles.yml +6 -0
  39. data/test/fixtures/boats.yml +6 -0
  40. data/test/fixtures/cars.yml +12 -0
  41. data/test/fixtures/electric_locomotives.yml +6 -0
  42. data/test/fixtures/electric_trains.yml +7 -0
  43. data/test/fixtures/maglev_locomotives.yml +7 -0
  44. data/test/fixtures/maglev_trains.yml +8 -0
  45. data/test/fixtures/migrations/1_add_class_table_inheritance.rb +15 -0
  46. data/test/fixtures/migrations/2_create_with_default_table.rb +19 -0
  47. data/test/fixtures/migrations/3_create_with_explicit_table.rb +11 -0
  48. data/test/fixtures/migrations/4_create_deeper_hierarchy.rb +11 -0
  49. data/test/fixtures/migrations/5_default_column_values.rb +13 -0
  50. data/test/fixtures/migrations/6_single_table_inheritance_view.rb +10 -0
  51. data/test/fixtures/migrations/7_second_deep_hierarchy.rb +70 -0
  52. data/test/fixtures/migrations/8_second_single_table_inheritance_view.rb +10 -0
  53. data/test/fixtures/rack_trains.yml +7 -0
  54. data/test/fixtures/steam_locomotives.yml +7 -0
  55. data/test/fixtures/steam_trains.yml +8 -0
  56. data/test/migration_test.rb +30 -0
  57. data/test/schema_test.rb +179 -0
  58. data/test/single_table_inheritance.rb +141 -0
  59. data/test/test_helper.rb +80 -0
  60. data/updateable_views_inheritance.gemspec +26 -0
  61. metadata +219 -0
@@ -0,0 +1,10 @@
1
+ class SingleTableInheritanceView < ActiveRecord::Migration
2
+ def self.up
3
+ rebuild_parent_and_children_views(:locomotives)
4
+ create_single_table_inheritance_view(:all_locomotives,:locomotives)
5
+ end
6
+
7
+ def self.down
8
+ drop_view(:all_locomotives)
9
+ end
10
+ end
@@ -0,0 +1,70 @@
1
+ class SecondDeepHierarchy < ActiveRecord::Migration
2
+ # Create tables and views for the following inheritance hierarchy:
3
+ #
4
+ # vehicles
5
+ # ____________________________|_______________________________
6
+ # | | |
7
+ # wheeled_vehicles railed_vehicles boats
8
+ # ____|_____ |
9
+ # | | |
10
+ # bicycles cars trains
11
+ # ________________|________________
12
+ # | | |
13
+ # steam_trains rack_trains electric_trains
14
+ # |
15
+ # maglev_trains
16
+ def self.up
17
+ create_table :vehicles do |t|
18
+ t.column :name, :string
19
+ t.column :vehicle_type, :string
20
+ end
21
+
22
+ create_child(:wheeled_vehicles, :parent => :vehicles) do |t|
23
+ t.column :number_of_wheels, :integer
24
+ end
25
+
26
+ create_child(:bicycles, :parent => :wheeled_vehicles) do |t|
27
+ t.column :number_of_gears, :integer
28
+ end
29
+
30
+ create_child(:cars, :parent => :wheeled_vehicles) do |t|
31
+ t.column :number_of_doors, :integer
32
+ end
33
+
34
+ create_child(:railed_vehicles, :parent => :vehicles) do |t|
35
+ t.column :number_of_rails, :integer
36
+ end
37
+
38
+ create_child(:trains, :parent => :railed_vehicles) do |t|
39
+ t.column :max_speed, :integer
40
+ end
41
+
42
+ create_child(:steam_trains, :parent => :trains) do |t|
43
+ t.column :water_consumption, :decimal, :precision => 6, :scale => 2
44
+ t.column :coal_consumption, :decimal, :precision => 6, :scale => 2
45
+ end
46
+
47
+ create_child(:rack_trains, :parent => :trains) do |t|
48
+ t.column :bidirectional, :boolean, :default => false
49
+ t.column :narrow_gauge, :boolean, :default => true
50
+ t.column :rail_system, :string, :default => 'Abt'
51
+ end
52
+
53
+ create_child(:electric_trains, :parent => :trains) do |t|
54
+ t.column :electricity_consumption, :decimal, :precision => 6, :scale => 2
55
+ end
56
+
57
+ create_child(:maglev_trains, :parent => :electric_trains) do |t|
58
+ t.column :magnetic_field, :integer
59
+ end
60
+
61
+ create_child(:boats, :parent => :vehicles) do |t|
62
+ t.column :mast_number, :integer
63
+ end
64
+ end
65
+
66
+ def self.down
67
+ %w(boats maglev_trains electric_trains steam_trains rack_trains trains railed_vehicles cars bicycles wheeled_vehicles).each{|child| drop_child(child)}
68
+ drop_table :vehicles
69
+ end
70
+ end
@@ -0,0 +1,10 @@
1
+ class SecondSingleTableInheritanceView < ActiveRecord::Migration
2
+ def self.up
3
+ rebuild_parent_and_children_views(:vehicles)
4
+ create_single_table_inheritance_view(:all_vehicles,:vehicles)
5
+ end
6
+
7
+ def self.down
8
+ drop_view(:all_vehicles)
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ rack:
2
+ id: 4
3
+ name: 'Rack'
4
+ vehicle_type: 'RackTrain'
5
+ number_of_rails: 2
6
+ max_speed: 100
7
+ bidirectional: true
@@ -0,0 +1,7 @@
1
+ rocket:
2
+ id: 1
3
+ name: 'Stephenson Rocket'
4
+ type: 'SteamLocomotive'
5
+ max_speed: 20
6
+ water_consumption: 13
7
+ coal_consumption: 20
@@ -0,0 +1,8 @@
1
+ steam_tr:
2
+ id: 3
3
+ name: 'Steam Train'
4
+ vehicle_type: 'SteamTrain'
5
+ number_of_rails: 2
6
+ max_speed: 21
7
+ water_consumption: 14
8
+ coal_consumption: 24
@@ -0,0 +1,30 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class ClassTableInheritanceMigrationTest < ActiveSupport::TestCase
4
+ # We use transactional fixtures - migration from the setup is rolled back by Rails on teardown
5
+ def setup
6
+ @connection = ActiveRecord::Base.connection
7
+ end
8
+
9
+ def test_create_child_default
10
+ ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 2)
11
+ assert_equal %w(coal_consumption id max_speed name type water_consumption),
12
+ @connection.columns(:steam_locomotives).map{ |c| c.name }.sort
13
+ end
14
+
15
+ def test_create_child_explicit_table
16
+ ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 3)
17
+ assert_equal %w(electricity_consumption id max_speed name type),
18
+ @connection.columns(:electric_locomotives).map{ |c| c.name }.sort
19
+ end
20
+
21
+ def test_drop_child
22
+ ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 3)
23
+ ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/', 2)
24
+ assert_equal %w(steam_locomotives), @connection.views.sort
25
+ assert_equal %w(locomotives
26
+ schema_migrations
27
+ steam_locomotives_data
28
+ updateable_views_inheritance), @connection.tables.sort
29
+ end
30
+ end
@@ -0,0 +1,179 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class ClassTableInheritanceSchemaTest < ActiveSupport::TestCase
4
+ def setup
5
+ ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 5)
6
+ @connection = ActiveRecord::Base.connection
7
+ end
8
+
9
+ def test_pk_and_sequence_for
10
+ assert_equal ['id', 'public.locomotives_id_seq'], @connection.pk_and_sequence_for(:maglev_locomotives), "Could not get pk and sequence for child aggregate view"
11
+ end
12
+
13
+ def test_primary_key
14
+ assert_equal 'id', @connection.primary_key(:maglev_locomotives), "Wrong or no primary key for child aggregate view"
15
+ end
16
+
17
+
18
+ def test_content_columns
19
+ assert !SteamLocomotive.content_columns.include?("id")
20
+ end
21
+
22
+ def test_views
23
+ assert_equal ["electric_locomotives", "maglev_locomotives", "rack_locomotives", "steam_locomotives"],
24
+ @connection.views.sort
25
+ end
26
+
27
+ class ParentTableWithOnlyOneColumn < ActiveRecord::Migration
28
+ def self.up
29
+ create_table(:parent_pk_only){}
30
+ create_table :child_data do |t|
31
+ t.column :name, :string
32
+ end
33
+ create_child_view :parent_pk_only, :child
34
+ end
35
+ end
36
+
37
+ def test_parent_table_with_only_one_column
38
+ ParentTableWithOnlyOneColumn.up
39
+ assert @connection.views.include?('child')
40
+ assert_equal %w(id name), @connection.columns(:child).map{|c| c.name}.sort
41
+ end
42
+
43
+ class ChildTableWithOnlyOneColumn < ActiveRecord::Migration
44
+ def self.up
45
+ create_table :parent do |t|
46
+ t.column :name, :string
47
+ end
48
+ create_table(:child_pk_only_data){}
49
+ create_child_view :parent, :child_pk_only
50
+ end
51
+ end
52
+
53
+ def test_child_table_with_only_one_column
54
+ ChildTableWithOnlyOneColumn.up
55
+ assert @connection.views.include?('child_pk_only'), "Could not create child view when child table has only one column"
56
+ assert_equal %w(id name), @connection.columns(:child_pk_only).map{|c| c.name}.sort
57
+ end
58
+
59
+ def test_serial_pk_has_default_in_view
60
+ assert_equal %q|nextval('locomotives_id_seq'::regclass)|,
61
+ @connection.query(<<-end_sql, 'Serial PK has default in view')[0][0]
62
+ SELECT pg_catalog.pg_get_expr(d.adbin, d.adrelid) as constraint
63
+ FROM pg_catalog.pg_attrdef d, pg_catalog.pg_attribute a, pg_catalog.pg_class c
64
+ WHERE d.adrelid = a.attrelid
65
+ AND d.adnum = a.attnum
66
+ AND a.atthasdef
67
+ AND c.relname = 'maglev_locomotives'
68
+ AND a.attrelid = c.oid
69
+ AND a.attname = 'id'
70
+ AND a.attnum > 0 AND NOT a.attisdropped
71
+ end_sql
72
+ end
73
+
74
+ def test_default_value_string_of_view_column
75
+ RackLocomotive.reset_column_information
76
+ assert_equal 'Abt', RackLocomotive.new.rail_system
77
+ end
78
+
79
+ def test_default_value_boolean_of_view_column
80
+ assert !RackLocomotive.new.bidirectional
81
+ assert RackLocomotive.new.narrow_gauge
82
+ end
83
+
84
+ class ChangeDefaultValueOfColumn < ActiveRecord::Migration
85
+ def self.up
86
+ remove_parent_and_children_views(:rack_locomotives)
87
+ change_column_default(:rack_locomotives_data, :rail_system, 'Marsh')
88
+ rebuild_parent_and_children_views(:rack_locomotives)
89
+ end
90
+ end
91
+
92
+ def test_change_default_value_of_column
93
+ ChangeDefaultValueOfColumn.up
94
+ RackLocomotive.reset_column_information
95
+ assert_equal 'Marsh', RackLocomotive.new.rail_system
96
+ end
97
+
98
+ class RemoveChildrenViews < ActiveRecord::Migration
99
+ def self.up
100
+ remove_parent_and_children_views(:locomotives)
101
+ end
102
+ end
103
+
104
+ def test_remove_parent_and_children_views
105
+ RemoveChildrenViews.up
106
+ assert @connection.views.empty?
107
+ end
108
+
109
+ class RemoveColumnInParentTable < ActiveRecord::Migration
110
+ def self.up
111
+ remove_parent_and_children_views(:locomotives)
112
+ remove_column(:locomotives, :max_speed)
113
+ rebuild_parent_and_children_views(:locomotives)
114
+ end
115
+ end
116
+
117
+ def test_remove_column_parent_table
118
+ RemoveColumnInParentTable.up
119
+ assert_equal %w(coal_consumption id name type water_consumption),
120
+ @connection.columns(:steam_locomotives).map{ |c| c.name }.sort
121
+ assert_equal %w(electricity_consumption id magnetic_field name type),
122
+ @connection.columns(:maglev_locomotives).map{ |c| c.name }.sort
123
+ end
124
+
125
+ class RenameColumnInParentTable < ActiveRecord::Migration
126
+ def self.up
127
+ ActiveRecord::Fixtures.create_fixtures(File.dirname(__FILE__) + '/fixtures/', :electric_locomotives)
128
+ ActiveRecord::Fixtures.create_fixtures(File.dirname(__FILE__) + '/fixtures/', :maglev_locomotives)
129
+ ActiveRecord::Fixtures.create_fixtures(File.dirname(__FILE__) + '/fixtures/', :steam_locomotives)
130
+ remove_parent_and_children_views(:locomotives)
131
+ rename_column(:locomotives, :max_speed, :maximal_speed)
132
+ rebuild_parent_and_children_views(:locomotives)
133
+
134
+ end
135
+ end
136
+
137
+ def test_rename_column_parent_table
138
+ RenameColumnInParentTable.up
139
+ assert_equal %w(coal_consumption id maximal_speed name type water_consumption),
140
+ @connection.columns(:steam_locomotives).map{ |c| c.name }.sort
141
+ assert_equal %w(electricity_consumption id magnetic_field maximal_speed name type),
142
+ @connection.columns(:maglev_locomotives).map{ |c| c.name }.sort
143
+
144
+ end
145
+
146
+ class AddColumnToParentTable < ActiveRecord::Migration
147
+ def self.up
148
+ add_column(:raw_electric_locomotives, :number_of_engines, :integer)
149
+ rebuild_parent_and_children_views(:electric_locomotives)
150
+ end
151
+ end
152
+
153
+ def test_add_column_to_parent_table
154
+ AddColumnToParentTable.up
155
+ assert_equal %w(electricity_consumption id max_speed name number_of_engines type),
156
+ @connection.columns(:electric_locomotives).map{ |c| c.name }.sort
157
+ assert_equal %w(electricity_consumption id magnetic_field max_speed name number_of_engines type),
158
+ @connection.columns(:maglev_locomotives).map{ |c| c.name }.sort
159
+
160
+ end
161
+
162
+ class ChangeChildRelationView < ActiveRecord::Migration
163
+ def self.up
164
+ remove_parent_and_children_views(:electric_locomotives)
165
+ rename_column(:raw_electric_locomotives, :electricity_consumption, :electric_consumption)
166
+ rebuild_parent_and_children_views(:electric_locomotives)
167
+ end
168
+ end
169
+
170
+ def test_change_child_relation_view
171
+ ChangeChildRelationView.up
172
+ assert_equal %w(electric_consumption id max_speed name type),
173
+ @connection.columns(:electric_locomotives).map{ |c| c.name }.sort
174
+ end
175
+
176
+ def test_table_exists
177
+ #TODO: test table_exists? monkey patch
178
+ end
179
+ end
@@ -0,0 +1,141 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class SingleTableInheritanceAggregateViewTest < ActiveSupport::TestCase
4
+ def setup
5
+ ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 6)
6
+ # order of fixtures is important for the test - last loaded should not be with max(id)
7
+ %w(electric_locomotives maglev_locomotives steam_locomotives).each do |f|
8
+ ActiveRecord::Fixtures.create_fixtures(File.dirname(__FILE__) + '/fixtures/', f)
9
+ end
10
+ @connection = ActiveRecord::Base.connection
11
+ end
12
+
13
+ def test_single_table_inheritance_view_schema
14
+ @connection = ActiveRecord::Base.connection
15
+ assert_equal %w(coal_consumption id max_speed name type water_consumption electricity_consumption bidirectional narrow_gauge magnetic_field rail_system).sort,
16
+ @connection.columns(:all_locomotives).map{ |c| c.name }.sort
17
+ end
18
+
19
+ def test_single_table_inheritance_records_number
20
+ assert_equal Locomotive.count, @connection.query("SELECT count(*) FROM all_locomotives").first.first.to_i
21
+ assert_equal SteamLocomotive.count, @connection.query("SELECT count(*) FROM all_locomotives WHERE type='SteamLocomotive'").first.first.to_i
22
+ assert_equal ElectricLocomotive.count - MaglevLocomotive.count, @connection.query("SELECT count(*) FROM all_locomotives WHERE type='ElectricLocomotive'").first.first.to_i
23
+ assert_equal RackLocomotive.count, @connection.query("SELECT count(*) FROM all_locomotives WHERE type='RackLocomotive'").first.first.to_i
24
+ assert_equal MaglevLocomotive.count, @connection.query("SELECT count(*) FROM all_locomotives WHERE type='MaglevLocomotive'").first.first.to_i
25
+ end
26
+
27
+ def test_single_table_inheritance_save
28
+ electric_locomotive = ElectricLocomotive.new(:name=> 'BoBo', :max_speed => 40, :electricity_consumption => 12)
29
+ assert electric_locomotive.save
30
+ assert_equal electric_locomotive.name, @connection.query("SELECT name FROm all_locomotives WHERE id=#{electric_locomotive.id}").first.first
31
+ end
32
+
33
+ class AddColumnToParentTable < ActiveRecord::Migration
34
+ def self.up
35
+ add_column(:raw_electric_locomotives, :number_of_engines, :integer)
36
+ drop_view(:all_locomotives)
37
+ rebuild_parent_and_children_views(:electric_locomotives)
38
+ create_single_table_inheritance_view(:all_locomotives, :locomotives)
39
+ end
40
+ end
41
+
42
+ def test_single_table_inheritance_view_add_column_to_parent_table
43
+ AddColumnToParentTable.up
44
+ assert_equal %w(coal_consumption id max_speed name type water_consumption electricity_consumption bidirectional narrow_gauge magnetic_field rail_system number_of_engines).sort,
45
+ @connection.columns(:all_locomotives).map{ |c| c.name }.sort
46
+ end
47
+
48
+ class RemoveColumnInParentTable < ActiveRecord::Migration
49
+ def self.up
50
+ drop_view(:all_locomotives)
51
+ remove_parent_and_children_views(:locomotives)
52
+ remove_column(:locomotives, :max_speed)
53
+ rebuild_parent_and_children_views(:locomotives)
54
+ create_single_table_inheritance_view(:all_locomotives,:locomotives)
55
+ end
56
+ end
57
+
58
+ def test_single_table_inheritance_view_remove_column_parent_table
59
+ RemoveColumnInParentTable.up
60
+ assert_equal %w(coal_consumption id name type water_consumption electricity_consumption bidirectional narrow_gauge magnetic_field rail_system).sort,
61
+ @connection.columns(:all_locomotives).map{ |c| c.name }.sort
62
+ end
63
+
64
+ class RenameColumnInParentTable < ActiveRecord::Migration
65
+ def self.up
66
+ drop_view(:all_locomotives)
67
+ remove_parent_and_children_views(:locomotives)
68
+ rename_column(:locomotives, :max_speed, :maximal_speed)
69
+ rebuild_parent_and_children_views(:locomotives)
70
+ create_single_table_inheritance_view(:all_locomotives, :locomotives)
71
+ end
72
+ end
73
+
74
+ def test_single_table_inheritance_view_rename_column_parent_table
75
+ RenameColumnInParentTable.up
76
+ assert_equal %w(coal_consumption id maximal_speed name type water_consumption electricity_consumption bidirectional narrow_gauge magnetic_field rail_system).sort,
77
+ @connection.columns(:all_locomotives).map{ |c| c.name }.sort
78
+ end
79
+
80
+ class ChangeChildRelationView < ActiveRecord::Migration
81
+ def self.up
82
+ drop_view(:all_locomotives)
83
+ remove_parent_and_children_views(:electric_locomotives)
84
+ rename_column(:raw_electric_locomotives, :electricity_consumption, :electric_consumption)
85
+ rebuild_parent_and_children_views(:electric_locomotives)
86
+ create_single_table_inheritance_view(:all_locomotives, :locomotives)
87
+ end
88
+ end
89
+
90
+ def test_single_table_inheritance_view_change_child_relation_view
91
+ ChangeChildRelationView.up
92
+ assert_equal %w(coal_consumption id max_speed name type water_consumption electric_consumption bidirectional narrow_gauge magnetic_field rail_system).sort,
93
+ @connection.columns(:all_locomotives).map{ |c| c.name }.sort
94
+ end
95
+
96
+ class ConflictColumns < ActiveRecord::Migration
97
+ def self.up
98
+ drop_view(:all_locomotives)
99
+ add_column(:raw_electric_locomotives, :number_of_engines, :integer)
100
+ add_column(:steam_locomotives_data, :number_of_engines, :string)
101
+ rebuild_parent_and_children_views(:electric_locomotives)
102
+ rebuild_parent_and_children_views(:steam_locomotives)
103
+ create_single_table_inheritance_view(:all_locomotives, :locomotives)
104
+ end
105
+ end
106
+
107
+ def test_single_table_inheritance_view_conflict_columns
108
+ ConflictColumns.up
109
+ assert_equal %w(coal_consumption id max_speed name type water_consumption electricity_consumption bidirectional narrow_gauge magnetic_field rail_system number_of_engines).sort,
110
+ @connection.columns(:all_locomotives).map{ |c| c.name }.sort
111
+ assert_equal 'text', @connection.columns(:all_locomotives).detect{|c| c.name == "number_of_engines"}.sql_type
112
+ end
113
+
114
+ class ConflictColumnsWithValues < ActiveRecord::Migration
115
+ def self.up
116
+ add_column(:raw_electric_locomotives, :number_of_engines, :integer)
117
+ add_column(:steam_locomotives_data, :number_of_engines, :string)
118
+ execute("UPDATE raw_electric_locomotives SET number_of_engines = 2")
119
+ execute("UPDATE steam_locomotives_data SET number_of_engines = 'one'")
120
+ drop_view(:all_locomotives)
121
+ rebuild_parent_and_children_views(:electric_locomotives)
122
+ rebuild_parent_and_children_views(:steam_locomotives)
123
+ create_single_table_inheritance_view(:all_locomotives, :locomotives)
124
+ end
125
+ end
126
+
127
+ def test_single_table_inheritance_view_conflict_columns_with_values
128
+ ConflictColumnsWithValues.up
129
+ assert_equal %w(coal_consumption id max_speed name type water_consumption electricity_consumption bidirectional narrow_gauge magnetic_field rail_system number_of_engines).sort,
130
+ @connection.columns(:all_locomotives).map{ |c| c.name }.sort
131
+ assert_equal 'text', @connection.columns(:all_locomotives).detect{|c| c.name == "number_of_engines"}.sql_type
132
+ assert_equal 'one', @connection.query("SELECT number_of_engines FROM all_locomotives WHERE id=#{SteamLocomotive.find(:first).id}").first.first
133
+ assert_equal '2', @connection.query("SELECT number_of_engines FROM all_locomotives WHERE id=#{ElectricLocomotive.find(:first).id}").first.first
134
+ end
135
+
136
+ def test_respond_to_missing_attributes
137
+ Locomotive.table_name = :all_locomotives
138
+ assert !MaglevLocomotive.new.respond_to?(:non_existing_attribute_in_the_hierarchy), "Active Record is gone haywire - responds to attributes that are never defined"
139
+ assert !MaglevLocomotive.new.respond_to?(:coal_consumption), "Responds to an attribute not defined in the class' view but in the STI view"
140
+ end
141
+ end