我想将多态关联与使用单表继承(STI)从基类派生的模型一起使用。我已经进一步调查了这个问题,并且(当然)通过stackoverflow挖掘,例如这里(ActiveRecord, has_many :through, and Polymorphic Associations)和那里(ActiveRecord, has_many :through, Polymorphic Associations with STI)。不幸的是,我发现的所有信息都认为是多态关联,而不是STI背景下的用法。
在我目前的项目中,我有一个设计,其中包含一个屏幕截图和许多链接到它的资产。某些资产(变体资产)也应该有链接到它们的屏幕截图。因为设计有很多资产,我想通过获取所有屏幕截图。
design.rb
class Design < ActiveRecord::Base
has_one :screenshot, as: :screenshotable, dependent: :destroy
has_many :assets, dependent: :destroy
has_many :screenshots, through: :assets
end
screenshot.rb
class Screenshot < ActiveRecord::Base
belongs_to :screenshotable, polymorphic: true
end
asset.rb
class Asset < ActiveRecord::Base
belongs_to :design
end
variation_asset.rb
class VariationAsset < Asset
# this is the important part as only a
# variation asset should have a screenshot
has_one :screenshot, as: :screenshotable, dependent: :destroy
end
将Screenshot
分配给VariationAsset
效果很好。使用Asset
尝试此操作会按预期(并且需要)引发NoMethodError
。因此,多态接口似乎可以工作,并在架构中正确设置。
schema.rb
create_table "screenshots", :force => true do |t|
t.string "name"
t.integer "screenshotable_id"
t.string "screenshotable_type"
end
create_table "assets", :force => true do |t|
t.string "name"
t.integer "design_id"
t.string "type"
end
从Screenshot
到Design
查询每个Asset
会引发以下错误:
active_record / reflection.rb:509:在`check_validity!'中:找不到源关联:screenshot或:模型资产中的屏幕截图。试试'has_many:screenshots,:through =&gt; :assets,:source =&gt; ”。它是一个:设计? (ActiveRecord的:: HasManyThroughSourceAssociationNotFoundError)
我按照错误消息中的建议使用:source
参数进行了尝试,但这也无济于事。
当我将has_one :screenshot, as: :screenshotable, dependent: :destroy
行放入STI基类Asset
时,它有效:
class Asset < ActiveRecord::Base
belongs_to :design
has_one :screenshot, as: :screenshotable, dependent: :destroy
end
我认为它与through:
参数有关,而且似乎(对我来说)不可能告诉它以某种方式调查VariationAsset
而不是Asset
这一事实
您可以在github repo找到上述代码的“工作”示例。
任何帮助表示赞赏! : - )