【问题标题】:How to form a polymorphic has_many on an inherited class如何在继承的类上形成多态 has_many
【发布时间】:2016-04-30 06:18:33
【问题描述】:

在 Rails 4.2 应用程序中,我有一个继承自 Draftsman 的模型。

module ActsAs
  class Draft < Draftsman::Draft
    include ActsAs::Votable
  end
end 

用户可以投票批准/拒绝编辑,ActsAs::Votable mixin 添加了这种多态关联和方法。

module ActsAs
  module Votable
    extend ActiveSupport::Concern
    included do
      has_many :votes_for, 
        class_name: 'ActsAs::Vote',
        as: :votable, 
        dependent: :destroy
    end
  end
end

这适用于大多数父模型,但我在使用这个继承的 Draftsman 类时遇到了问题。

我可以创建投票

ActsAs::Vote.last
=> #<ActsAs::Vote id: 10, votable_id: 6, votable_type: "Draftsman::Draft">

但我无法退回草稿的选票

@draft = ActsAs::Draft.find(6)
@draft.votes_for
=> #<ActiveRecord::Associations::CollectionProxy []>

我尝试修改投票创建方法以将 votable_type 设置为 ActsAs::Draft 而不是继承的 Draftsman::Draft,但同样的问题仍然存在。

ActsAs::Vote.last
=> #<ActsAs::Vote id: 10, votable_id: 6, votable_type: "ActsAs::Draft">
@draft = ActsAs::Draft.find(6)
@draft.votes_for
=> #<ActiveRecord::Associations::CollectionProxy []>

Draftsmans::Draft 上显然没有定义关系

@draft = Draftsman::Draft.find(6)
@draft.votes_for
NoMethodError: undefined method `votes_for' for #<Draftsman::Draft:0x007fd7e6de9660>

ActsAs::Vote.all显示表中存在记录时,为什么我无法通过@draft获取子投票?

【问题讨论】:

    标签: ruby-on-rails inheritance sti


    【解决方案1】:

    这是使用 STI 的多态关联时的一个已知问题。

    见:Why polymorphic association doesn't work for STI if type column of the polymorphic association doesn't point to the base model of STI?

    就我个人而言,我正在使用 store_base_sti_class(宝石:https://github.com/appfolio/store_base_sti_class)自己处理这个问题,它使用 Rails 修补 STI 行为。

    【讨论】:

    • 谢谢@anthony,我已经遇到过这个问题,但是这个评论让我相信我应该可以给孩子投票:Rails transparently uses the STI base classname Staff as the target type and due to the fact that id's are always unique in an STI table it makes no difference whether the type is set to Guard or to Staff in the poly table the correct record will be fetched. 但也许我误解了这个评论。无论如何,如果我设置votable_type: "ActsAs::Draft",我希望能够调用ActAs::Draft.find(:id).votes_for,对吗?但我仍然得到一个空集合。
    • 感谢您对此的看法。我想我可能遗漏了一些东西,因此感谢您提供的任何帮助或想法。
    • 没关系。我肯定在其他地方遇到了错误,因为它现在按预期工作,我确实可以致电ActAs::Draft.find(:id).votes_for。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-10
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    • 2012-03-06
    • 2023-03-14
    相关资源
    最近更新 更多