我这里有一个多态关联和STI的案例。

# app/models/car.rb
class Car < ActiveRecord::Base
  belongs_to :borrowable, :polymorphic => true
end

# app/models/staff.rb
class Staff < ActiveRecord::Base
  has_one :car, :as => :borrowable, :dependent => :destroy
end

# app/models/guard.rb
class Guard < Staff
end

为了使多态关联起作用,根据有关多态关联的API文档,http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Polymorphic+Associations,我必须将borrowable_type设置为STI模型的base_class,在我的情况下为Staff

问题是:如果将borrowable_type设置为STI类,为什么它不起作用?

一些测试以证明这一点:
# now the test speaks only truth

# test/fixtures/cars.yml
one:
  name: Enzo
  borrowable: staff (Staff)

two:
  name: Mustang
  borrowable: guard (Guard)

# test/fixtures/staffs.yml
staff:
  name: Jullia Gillard

guard:
  name: Joni Bravo
  type: Guard

# test/units/car_test.rb

require 'test_helper'

class CarTest < ActiveSupport::TestCase
  setup do
    @staff = staffs(:staff)
    @guard = staffs(:guard)
  end

  test "should be destroyed if an associated staff is destroyed" do
    assert_difference('Car.count', -1) do
      @staff.destroy
    end
  end

  test "should be destroyed if an associated guard is destroyed" do
    assert_difference('Car.count', -1) do
      @guard.destroy
    end
  end

end

但是,似乎只有员工实例才是真实的。结果是:
# Running tests:

F.

Finished tests in 0.146657s, 13.6373 tests/s, 13.6373 assertions/s.

  1) Failure:
test_should_be_destroyed_if_an_associated_guard_is_destroyed(CarTest) [/private/tmp/guineapig/test/unit/car_test.rb:16]:
"Car.count" didn't change by -1.
<1> expected but was
<2>.

谢谢

最佳答案

好问题。使用Rails 3.1时,我遇到了完全相同的问题。看起来您无法执行此操作,因为它不起作用。可能是预期的行为。显然,在Rails中结合使用多态关联和单表继承(STI)有点复杂。

当前有关Rails 3.2的Rails文档为结合polymorphic associations and STI提供了以下建议:



在您的情况下,基本模型将为“Staff”,即,所有项目的“borrowable_type”应为“Staff”,而不是“Guard”。通过使用“becomes”:guard.becomes(Staff)可以使派生类显示为基类。可以将“borrowable_type”列直接设置为基类“Staff”,或者按照Rails文档的建议,使用

class Car < ActiveRecord::Base
  ..
  def borrowable_type=(sType)
     super(sType.to_s.classify.constantize.base_class.to_s)
  end

10-01 02:19