inheritance_test.rb 19.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
require "cases/helper"
require "models/author"
require "models/company"
require "models/person"
require "models/post"
require "models/project"
require "models/subscriber"
require "models/vegetables"
require "models/shop"
require "models/sponsor"
D
Initial  
David Heinemeier Hansson 已提交
11

12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
module InheritanceTestHelper
  def with_store_full_sti_class(&block)
    assign_store_full_sti_class true, &block
  end

  def without_store_full_sti_class(&block)
    assign_store_full_sti_class false, &block
  end

  def assign_store_full_sti_class(flag)
    old_store_full_sti_class = ActiveRecord::Base.store_full_sti_class
    ActiveRecord::Base.store_full_sti_class = flag
    yield
  ensure
    ActiveRecord::Base.store_full_sti_class = old_store_full_sti_class
  end
end

30
class InheritanceTest < ActiveRecord::TestCase
31
  include InheritanceTestHelper
32
  fixtures :companies, :projects, :subscribers, :accounts, :vegetables
33 34

  def test_class_with_store_full_sti_class_returns_full_name
35
    with_store_full_sti_class do
36
      assert_equal "Namespaced::Company", Namespaced::Company.sti_name
37
    end
38 39
  end

40
  def test_class_with_blank_sti_name
41
    company = Company.first
A
Aaron Patterson 已提交
42
    company = company.dup
43
    company.extend(Module.new {
44
      def _read_attribute(name)
45
        return "  " if name == "type"
46 47 48 49
        super
      end
    })
    company.save!
J
Jon Leighton 已提交
50
    company = Company.all.to_a.find { |x| x.id == company.id }
51
    assert_equal "  ", company.type
52 53
  end

54
  def test_class_without_store_full_sti_class_returns_demodulized_name
55
    without_store_full_sti_class do
56
      assert_equal "Company", Namespaced::Company.sti_name
57
    end
58 59
  end

60
  def test_compute_type_success
61
    assert_equal Author, ActiveRecord::Base.send(:compute_type, "Author")
62 63 64 65
  end

  def test_compute_type_nonexistent_constant
    e = assert_raises NameError do
66
      ActiveRecord::Base.send :compute_type, "NonexistentModel"
67
    end
68 69
    assert_equal "uninitialized constant ActiveRecord::Base::NonexistentModel", e.message
    assert_equal "ActiveRecord::Base::NonexistentModel", e.name
70 71 72 73 74
  end

  def test_compute_type_no_method_error
    ActiveSupport::Dependencies.stub(:safe_constantize, proc{ raise NoMethodError }) do
      assert_raises NoMethodError do
75
        ActiveRecord::Base.send :compute_type, "InvalidModel"
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
      end
    end
  end

  def test_compute_type_on_undefined_method
    error = nil
    begin
      Class.new(Author) do
        alias_method :foo, :bar
      end
    rescue => e
      error = e
    end

    ActiveSupport::Dependencies.stub(:safe_constantize, proc{ raise e }) do

      exception = assert_raises NameError do
93
        ActiveRecord::Base.send :compute_type, "InvalidModel"
94 95 96 97 98 99 100 101
      end
      assert_equal error.message, exception.message
    end
  end

  def test_compute_type_argument_error
    ActiveSupport::Dependencies.stub(:safe_constantize, proc{ raise ArgumentError }) do
      assert_raises ArgumentError do
102
        ActiveRecord::Base.send :compute_type, "InvalidModel"
103 104 105 106
      end
    end
  end

107
  def test_should_store_demodulized_class_name_with_store_full_sti_class_option_disabled
108 109
    without_store_full_sti_class do
      item = Namespaced::Company.new
110
      assert_equal "Company", item[:type]
111
    end
112
  end
113

114
  def test_should_store_full_class_name_with_store_full_sti_class_option_enabled
115 116
    with_store_full_sti_class do
      item = Namespaced::Company.new
117
      assert_equal "Namespaced::Company", item[:type]
118
    end
119
  end
120

121
  def test_different_namespace_subclass_should_load_correctly_with_store_full_sti_class_option
122 123 124 125 126
    with_store_full_sti_class do
      item = Namespaced::Company.create name: "Wolverine 2"
      assert_not_nil Company.find(item.id)
      assert_not_nil Namespaced::Company.find(item.id)
    end
127
  end
D
Initial  
David Heinemeier Hansson 已提交
128

129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
  def test_descends_from_active_record
    assert !ActiveRecord::Base.descends_from_active_record?

    # Abstract subclass of AR::Base.
    assert LoosePerson.descends_from_active_record?

    # Concrete subclass of an abstract class.
    assert LooseDescendant.descends_from_active_record?

    # Concrete subclass of AR::Base.
    assert TightPerson.descends_from_active_record?

    # Concrete subclass of a concrete class but has no type column.
    assert TightDescendant.descends_from_active_record?

    # Concrete subclass of AR::Base.
    assert Post.descends_from_active_record?

    # Abstract subclass of a concrete class which has a type column.
    # This is pathological, as you'll never have Sub < Abstract < Concrete.
    assert !StiPost.descends_from_active_record?

    # Concrete subclasses an abstract class which has a type column.
    assert !SubStiPost.descends_from_active_record?
  end

155
  def test_company_descends_from_active_record
156
    assert !ActiveRecord::Base.descends_from_active_record?
157 158 159
    assert AbstractCompany.descends_from_active_record?, "AbstractCompany should descend from ActiveRecord::Base"
    assert Company.descends_from_active_record?, "Company should descend from ActiveRecord::Base"
    assert !Class.new(Company).descends_from_active_record?, "Company subclass should not descend from ActiveRecord::Base"
160 161
  end

162 163 164 165 166 167
  def test_abstract_class
    assert !ActiveRecord::Base.abstract_class?
    assert LoosePerson.abstract_class?
    assert !LooseDescendant.abstract_class?
  end

168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
  def test_inheritance_base_class
    assert_equal Post, Post.base_class
    assert_equal Post, SpecialPost.base_class
    assert_equal Post, StiPost.base_class
    assert_equal SubStiPost, SubStiPost.base_class
  end

  def test_abstract_inheritance_base_class
    assert_equal LoosePerson, LoosePerson.base_class
    assert_equal LooseDescendant, LooseDescendant.base_class
    assert_equal TightPerson, TightPerson.base_class
    assert_equal TightPerson, TightDescendant.base_class
  end

  def test_base_class_activerecord_error
J
Jon Leighton 已提交
183
    klass = Class.new { include ActiveRecord::Inheritance }
184 185 186
    assert_raise(ActiveRecord::ActiveRecordError) { klass.base_class }
  end

187
  def test_a_bad_type_column
188
    Company.connection.insert "INSERT INTO companies (id, #{QUOTED_TYPE}, name) VALUES(100, 'bad_class!', 'Not happening')"
189

190
    assert_raise(ActiveRecord::SubclassNotFound) { Company.find(100) }
D
Initial  
David Heinemeier Hansson 已提交
191 192 193
  end

  def test_inheritance_find
194 195 196 197
    assert_kind_of Firm, Company.find(1), "37signals should be a firm"
    assert_kind_of Firm, Firm.find(1), "37signals should be a firm"
    assert_kind_of Client, Company.find(2), "Summit should be a client"
    assert_kind_of Client, Client.find(2), "Summit should be a client"
D
Initial  
David Heinemeier Hansson 已提交
198
  end
J
Jeremy Kemper 已提交
199

D
Initial  
David Heinemeier Hansson 已提交
200
  def test_alt_inheritance_find
201 202 203 204
    assert_kind_of Cucumber, Vegetable.find(1)
    assert_kind_of Cucumber, Cucumber.find(1)
    assert_kind_of Cabbage, Vegetable.find(2)
    assert_kind_of Cabbage, Cabbage.find(2)
D
Initial  
David Heinemeier Hansson 已提交
205 206
  end

207 208 209 210 211 212 213
  def test_alt_becomes_works_with_sti
    vegetable = Vegetable.find(1)
    assert_kind_of Vegetable, vegetable
    cabbage = vegetable.becomes(Cabbage)
    assert_kind_of Cabbage, cabbage
  end

214 215 216
  def test_becomes_and_change_tracking_for_inheritance_columns
    cucumber = Vegetable.find(1)
    cabbage = cucumber.becomes!(Cabbage)
217
    assert_equal ["Cucumber", "Cabbage"], cabbage.custom_type_change
218 219
  end

220 221 222 223 224 225 226 227 228 229 230
  def test_alt_becomes_bang_resets_inheritance_type_column
    vegetable = Vegetable.create!(name: "Red Pepper")
    assert_nil vegetable.custom_type

    cabbage = vegetable.becomes!(Cabbage)
    assert_equal "Cabbage", cabbage.custom_type

    vegetable = cabbage.becomes!(Vegetable)
    assert_nil cabbage.custom_type
  end

D
Initial  
David Heinemeier Hansson 已提交
231
  def test_inheritance_find_all
232
    companies = Company.all.merge!(order: "id").to_a
233 234
    assert_kind_of Firm, companies[0], "37signals should be a firm"
    assert_kind_of Client, companies[1], "Summit should be a client"
D
Initial  
David Heinemeier Hansson 已提交
235
  end
J
Jeremy Kemper 已提交
236

D
Initial  
David Heinemeier Hansson 已提交
237
  def test_alt_inheritance_find_all
238
    companies = Vegetable.all.merge!(order: "id").to_a
239 240
    assert_kind_of Cucumber, companies[0]
    assert_kind_of Cabbage, companies[1]
D
Initial  
David Heinemeier Hansson 已提交
241 242 243 244 245 246
  end

  def test_inheritance_save
    firm = Firm.new
    firm.name = "Next Angle"
    firm.save
J
Jeremy Kemper 已提交
247

D
Initial  
David Heinemeier Hansson 已提交
248
    next_angle = Company.find(firm.id)
249
    assert_kind_of Firm, next_angle, "Next Angle should be a firm"
D
Initial  
David Heinemeier Hansson 已提交
250
  end
J
Jeremy Kemper 已提交
251

D
Initial  
David Heinemeier Hansson 已提交
252
  def test_alt_inheritance_save
253
    cabbage = Cabbage.new(name: "Savoy")
254 255 256 257
    cabbage.save!

    savoy = Vegetable.find(cabbage.id)
    assert_kind_of Cabbage, savoy
D
Initial  
David Heinemeier Hansson 已提交
258 259
  end

260 261
  def test_inheritance_new_with_default_class
    company = Company.new
262
    assert_equal Company, company.class
263 264 265
  end

  def test_inheritance_new_with_base_class
266
    company = Company.new(type: "Company")
267
    assert_equal Company, company.class
268 269 270
  end

  def test_inheritance_new_with_subclass
271
    firm = Company.new(type: "Firm")
272
    assert_equal Firm, firm.class
273 274
  end

275 276 277 278
  def test_new_with_abstract_class
    e = assert_raises(NotImplementedError) do
      AbstractCompany.new
    end
279
    assert_equal("AbstractCompany is an abstract class and cannot be instantiated.", e.message)
280 281 282 283 284 285
  end

  def test_new_with_ar_base
    e = assert_raises(NotImplementedError) do
      ActiveRecord::Base.new
    end
286
    assert_equal("ActiveRecord::Base is an abstract class and cannot be instantiated.", e.message)
287 288
  end

289
  def test_new_with_invalid_type
290
    assert_raise(ActiveRecord::SubclassNotFound) { Company.new(type: "InvalidType") }
291 292 293
  end

  def test_new_with_unrelated_type
294
    assert_raise(ActiveRecord::SubclassNotFound) { Company.new(type: "Account") }
295 296
  end

297 298 299
  def test_new_with_unrelated_namespaced_type
    without_store_full_sti_class do
      e = assert_raises ActiveRecord::SubclassNotFound do
300
        Namespaced::Company.new(type: "Firm")
301 302 303 304 305 306
      end

      assert_equal "Invalid single-table inheritance type: Namespaced::Firm is not a subclass of Namespaced::Company", e.message
    end
  end

307
  def test_new_with_complex_inheritance
308
    assert_nothing_raised { Client.new(type: "VerySpecialClient") }
309 310
  end

311 312
  def test_new_without_storing_full_sti_class
    without_store_full_sti_class do
313
      item = Company.new(type: "SpecialCo")
314 315 316 317
      assert_instance_of Company::SpecialCo, item
    end
  end

318
  def test_new_with_autoload_paths
319
    path = File.expand_path("../../models/autoloadable", __FILE__)
320 321
    ActiveSupport::Dependencies.autoload_paths << path

322
    firm = Company.new(type: "ExtraFirm")
323 324 325 326 327 328
    assert_equal ExtraFirm, firm.class
  ensure
    ActiveSupport::Dependencies.autoload_paths.reject! { |p| p == path }
    ActiveSupport::Dependencies.clear
  end

D
Initial  
David Heinemeier Hansson 已提交
329
  def test_inheritance_condition
330
    assert_equal 11, Company.count
331
    assert_equal 2, Firm.count
332
    assert_equal 5, Client.count
D
Initial  
David Heinemeier Hansson 已提交
333
  end
J
Jeremy Kemper 已提交
334

D
Initial  
David Heinemeier Hansson 已提交
335
  def test_alt_inheritance_condition
336 337 338
    assert_equal 4, Vegetable.count
    assert_equal 1, Cucumber.count
    assert_equal 3, Cabbage.count
D
Initial  
David Heinemeier Hansson 已提交
339 340 341
  end

  def test_finding_incorrect_type_data
342
    assert_raise(ActiveRecord::RecordNotFound) { Firm.find(2) }
D
Initial  
David Heinemeier Hansson 已提交
343 344
    assert_nothing_raised   { Firm.find(1) }
  end
J
Jeremy Kemper 已提交
345

D
Initial  
David Heinemeier Hansson 已提交
346
  def test_alt_finding_incorrect_type_data
347 348
    assert_raise(ActiveRecord::RecordNotFound) { Cucumber.find(2) }
    assert_nothing_raised   { Cucumber.find(1) }
D
Initial  
David Heinemeier Hansson 已提交
349 350 351 352
  end

  def test_update_all_within_inheritance
    Client.update_all "name = 'I am a client'"
J
Jon Leighton 已提交
353
    assert_equal "I am a client", Client.first.name
354
    # Order by added as otherwise Oracle tests were failing because of different order of results
355
    assert_equal "37signals", Firm.all.merge!(order: "id").to_a.first.name
D
Initial  
David Heinemeier Hansson 已提交
356
  end
J
Jeremy Kemper 已提交
357

D
Initial  
David Heinemeier Hansson 已提交
358
  def test_alt_update_all_within_inheritance
359 360 361
    Cabbage.update_all "name = 'the cabbage'"
    assert_equal "the cabbage", Cabbage.first.name
    assert_equal ["my cucumber"], Cucumber.all.map(&:name).uniq
D
Initial  
David Heinemeier Hansson 已提交
362 363 364 365
  end

  def test_destroy_all_within_inheritance
    Client.destroy_all
366 367
    assert_equal 0, Client.count
    assert_equal 2, Firm.count
D
Initial  
David Heinemeier Hansson 已提交
368
  end
J
Jeremy Kemper 已提交
369

D
Initial  
David Heinemeier Hansson 已提交
370
  def test_alt_destroy_all_within_inheritance
371 372 373
    Cabbage.destroy_all
    assert_equal 0, Cabbage.count
    assert_equal 1, Cucumber.count
D
Initial  
David Heinemeier Hansson 已提交
374 375 376
  end

  def test_find_first_within_inheritance
377 378 379
    assert_kind_of Firm, Company.all.merge!(where: "name = '37signals'").first
    assert_kind_of Firm, Firm.all.merge!(where: "name = '37signals'").first
    assert_nil Client.all.merge!(where: "name = '37signals'").first
D
Initial  
David Heinemeier Hansson 已提交
380
  end
J
Jeremy Kemper 已提交
381

D
Initial  
David Heinemeier Hansson 已提交
382
  def test_alt_find_first_within_inheritance
383 384 385
    assert_kind_of Cabbage, Vegetable.all.merge!(where: "name = 'his cabbage'").first
    assert_kind_of Cabbage, Cabbage.all.merge!(where: "name = 'his cabbage'").first
    assert_nil Cucumber.all.merge!(where: "name = 'his cabbage'").first
D
Initial  
David Heinemeier Hansson 已提交
386 387 388 389
  end

  def test_complex_inheritance
    very_special_client = VerySpecialClient.create("name" => "veryspecial")
390
    assert_equal very_special_client, VerySpecialClient.where("name = 'veryspecial'").first
391 392 393 394
    assert_equal very_special_client, SpecialClient.all.merge!(where: "name = 'veryspecial'").first
    assert_equal very_special_client, Company.all.merge!(where: "name = 'veryspecial'").first
    assert_equal very_special_client, Client.all.merge!(where: "name = 'veryspecial'").first
    assert_equal 1, Client.all.merge!(where: "name = 'Summit'").to_a.size
D
Initial  
David Heinemeier Hansson 已提交
395 396 397 398
    assert_equal very_special_client, Client.find(very_special_client.id)
  end

  def test_alt_complex_inheritance
399 400
    king_cole = KingCole.create("name" => "uniform heads")
    assert_equal king_cole, KingCole.where("name = 'uniform heads'").first
401 402 403 404
    assert_equal king_cole, GreenCabbage.all.merge!(where: "name = 'uniform heads'").first
    assert_equal king_cole, Cabbage.all.merge!(where: "name = 'uniform heads'").first
    assert_equal king_cole, Vegetable.all.merge!(where: "name = 'uniform heads'").first
    assert_equal 1, Cabbage.all.merge!(where: "name = 'his cabbage'").to_a.size
405
    assert_equal king_cole, Cabbage.find(king_cole.id)
D
Initial  
David Heinemeier Hansson 已提交
406
  end
J
Jeremy Kemper 已提交
407

408
  def test_eager_load_belongs_to_something_inherited
409
    account = Account.all.merge!(includes: :firm).find(1)
410
    assert account.association(:firm).loaded?, "association was not eager loaded"
411
  end
J
Jeremy Kemper 已提交
412

413
  def test_alt_eager_loading
414
    cabbage = RedCabbage.all.merge!(includes: :seller).find(4)
415
    assert cabbage.association(:seller).loaded?, "association was not eager loaded"
416 417
  end

418 419
  def test_eager_load_belongs_to_primary_key_quoting
    con = Account.connection
420
    assert_sql(/#{con.quote_table_name('companies')}.#{con.quote_column_name('id')} = 1/) do
421
      Account.all.merge!(includes: :firm).find(1)
422 423 424
    end
  end

425 426 427 428
  def test_inherits_custom_primary_key
    assert_equal Subscriber.primary_key, SpecialSubscriber.primary_key
  end

429
  def test_inheritance_without_mapping
430
    assert_kind_of SpecialSubscriber, SpecialSubscriber.find("webster132")
431
    assert_nothing_raised { s = SpecialSubscriber.new("name" => "And breaaaaathe!"); s.id = "roger"; s.save }
432
  end
433

434
  def test_scope_inherited_properly
435 436
    assert_nothing_raised { Company.of_first_firm }
    assert_nothing_raised { Client.of_first_firm }
437 438
  end
end
439

440
class InheritanceComputeTypeTest < ActiveRecord::TestCase
441
  include InheritanceTestHelper
442 443
  fixtures :companies

G
Guo Xiang Tan 已提交
444
  teardown do
445 446 447 448 449
    self.class.const_remove :FirmOnTheFly rescue nil
    Firm.const_remove :FirmOnTheFly rescue nil
  end

  def test_instantiation_doesnt_try_to_require_corresponding_file
450 451
    without_store_full_sti_class do
      foo = Firm.first.clone
452
      foo.type = "FirmOnTheFly"
453
      foo.save!
454

455 456
      # Should fail without FirmOnTheFly in the type condition.
      assert_raise(ActiveRecord::RecordNotFound) { Firm.find(foo.id) }
457

458 459 460
      # Nest FirmOnTheFly in the test case where Dependencies won't see it.
      self.class.const_set :FirmOnTheFly, Class.new(Firm)
      assert_raise(ActiveRecord::SubclassNotFound) { Firm.find(foo.id) }
461

462 463 464
      # Nest FirmOnTheFly in Firm where Dependencies will see it.
      # This is analogous to nesting models in a migration.
      Firm.const_set :FirmOnTheFly, Class.new(Firm)
465

466 467 468 469
      # And instantiate will find the existing constant rather than trying
      # to require firm_on_the_fly.
      assert_nothing_raised { assert_kind_of Firm::FirmOnTheFly, Firm.find(foo.id) }
    end
470
  end
471 472

  def test_sti_type_from_attributes_disabled_in_non_sti_class
473
    phone = Shop::Product::Type.new(name: "Phone")
474
    product = Shop::Product.new(type: phone)
475 476
    assert product.save
  end
477 478 479

  def test_inheritance_new_with_subclass_as_default
    original_type = Company.columns_hash["type"].default
480
    ActiveRecord::Base.connection.change_column_default :companies, :type, "Firm"
481
    Company.reset_column_information
482 483

    firm = Company.new # without arguments
484
    assert_equal "Firm", firm.type
485
    assert_instance_of Firm, firm
486

487 488
    firm = Company.new(firm_name: "Shri Hans Plastic") # with arguments
    assert_equal "Firm", firm.type
489
    assert_instance_of Firm, firm
490

491
    client = Client.new
492
    assert_equal "Client", client.type
493 494
    assert_instance_of Client, client

495 496
    firm = Company.new(type: "Client") # overwrite the default type
    assert_equal "Client", firm.type
497 498 499 500 501
    assert_instance_of Client, firm
  ensure
    ActiveRecord::Base.connection.change_column_default :companies, :type, original_type
    Company.reset_column_information
  end
502
end
503 504 505

class InheritanceAttributeTest < ActiveRecord::TestCase
  class Company < ActiveRecord::Base
506
    self.table_name = "companies"
507 508 509 510 511 512 513 514 515 516 517
    attribute :type, :string, default: "InheritanceAttributeTest::Startup"
  end

  class Startup < Company
  end

  class Empire < Company
  end

  def test_inheritance_new_with_subclass_as_default
    startup = Company.new # without arguments
518
    assert_equal "InheritanceAttributeTest::Startup", startup.type
519 520
    assert_instance_of Startup, startup

521 522
    empire = Company.new(type: "InheritanceAttributeTest::Empire") # without arguments
    assert_equal "InheritanceAttributeTest::Empire", empire.type
523 524 525
    assert_instance_of Empire, empire
  end
end
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556

class InheritanceAttributeMappingTest < ActiveRecord::TestCase
  setup do
    @old_registry = ActiveRecord::Type.registry
    ActiveRecord::Type.registry = ActiveRecord::Type::AdapterSpecificRegistry.new
    ActiveRecord::Type.register :omg_sti, InheritanceAttributeMappingTest::OmgStiType
    Company.delete_all
    Sponsor.delete_all
  end

  teardown do
    ActiveRecord::Type.registry = @old_registry
  end

  class OmgStiType < ActiveRecord::Type::String
    def cast_value(value)
      if value =~ /\Aomg_(.+)\z/
        $1.classify
      else
        value
      end
    end

    def serialize(value)
      if value
        "omg_%s" % value.underscore
      end
    end
  end

  class Company < ActiveRecord::Base
557
    self.table_name = "companies"
558 559 560 561 562 563 564
    attribute :type, :omg_sti
  end

  class Startup < Company; end
  class Empire < Company; end

  class Sponsor < ActiveRecord::Base
565
    self.table_name = "sponsors"
566 567 568 569 570 571
    attribute :sponsorable_type, :omg_sti

    belongs_to :sponsorable, polymorphic: true
  end

  def test_sti_with_custom_type
572 573
    Startup.create! name: "a Startup"
    Empire.create! name: "an Empire"
574 575

    assert_equal [["a Startup", "omg_inheritance_attribute_mapping_test/startup"],
576
                  ["an Empire", "omg_inheritance_attribute_mapping_test/empire"]], ActiveRecord::Base.connection.select_rows("SELECT name, type FROM companies").sort
577
    assert_equal [["a Startup", "InheritanceAttributeMappingTest::Startup"],
578
                  ["an Empire", "InheritanceAttributeMappingTest::Empire"]], Company.all.map { |a| [a.name, a.type] }.sort
579 580 581 582 583 584

    startup = Startup.first
    startup.becomes! Empire
    startup.save!

    assert_equal [["a Startup", "omg_inheritance_attribute_mapping_test/empire"],
585
                  ["an Empire", "omg_inheritance_attribute_mapping_test/empire"]], ActiveRecord::Base.connection.select_rows("SELECT name, type FROM companies").sort
586

587
    assert_equal [["a Startup", "InheritanceAttributeMappingTest::Empire"],
588
                  ["an Empire", "InheritanceAttributeMappingTest::Empire"]], Company.all.map { |a| [a.name, a.type] }.sort
589 590 591
  end

  def test_polymorphic_associations_custom_type
592
    startup = Startup.create! name: "a Startup"
593 594
    sponsor = Sponsor.create! sponsorable: startup

595
    assert_equal ["omg_inheritance_attribute_mapping_test/company"], ActiveRecord::Base.connection.select_values("SELECT sponsorable_type FROM sponsors")
596 597 598 599 600

    sponsor = Sponsor.first
    assert_equal startup, sponsor.sponsorable
  end
end