Ruby on rails 对于具有单表继承的ActiveRecord多态关联,是否确实需要重写`*\u type=`方法?

Ruby on rails 对于具有单表继承的ActiveRecord多态关联,是否确实需要重写`*\u type=`方法?,ruby-on-rails,ruby,activerecord,Ruby On Rails,Ruby,Activerecord,我正在重构一些处理多态关联的代码,这些关联可以接收实现单表继承的模型。当前代码遵循ActiveRecord文档中的建议,即最好覆盖attachable\u type=,以便将STI模型的基类名称存储在attachable\u type字段中: class Asset < ActiveRecord::Base belongs_to :attachable, polymorphic: true def attachable_type=(class_name) super(c

我正在重构一些处理多态
关联的代码,这些关联可以接收实现单表继承的模型。当前代码遵循
ActiveRecord
文档中的建议,即最好覆盖
attachable\u type=
,以便将STI模型的基类名称存储在
attachable\u type
字段中:

class Asset < ActiveRecord::Base
  belongs_to :attachable, polymorphic: true

  def attachable_type=(class_name)
     super(class_name.constantize.base_class.to_s)
  end
end

class Post < ActiveRecord::Base
  # because we store "Post" in attachable_type now dependent: :destroy will work
  has_many :assets, as: :attachable, dependent: :destroy
end

class GuestPost < Post
end

class MemberPost < Post
end
class资产
我知道我们希望存储该基类,以便
ActiveRecord
按预期工作。然而,当我测试了一些场景(包括文档中的场景)时,似乎没有必要重写
attachable\u type=
ActiveRecord
似乎已经处理了这种情况,并且总是存储基本模型
Post
,而不是
GuestPost
MemberPost

我创建了一个用于实现文档中的模型,并允许您处理一些数据并亲自查看。我无法重现文档一直试图回避的问题,直到
ActiveRecord
3.2.22.5版(除此之外我还没有尝试过)

有人知道是否真的需要覆盖
attachable\u type=
?文件是否过期了?或者它只是解决了直接运行
Asset.new attachable_type:'MemberPost',attachable_id:member_post.id
而不是
Asset.new attachable:member_post
的用例


这对我很重要的原因是我们有5个模型可能会受到影响。我们当前的代码实现了覆盖其中的3个,我正在进行重构,以使其干燥,并有可能将其引入另外2个模型中,在这些模型中,我们忘记了遵循此建议。

好的,我相信我更好地理解其背后的原因。当需要从表单创建或更新模型时,这是一个问题

在这种情况下,
attachable_type
attachable_id
被发送到控制器,控制器通常将此数据传递给模型。如果不重写
attachable_type=
模型将最终拥有
attachable_type
作为子类之一
GuestPost
MemberPost

这进而导致一系列问题。例如,即使在
关联中指定了
dependent::destroy
,当资产的所有者被销毁时,资产也不会被销毁

因此,如果期望您的模型通过表单接收多态关联字段的数据,则应该重写此方法


我更新了回购协议来证明这个问题。

通常你会选择STI或多态关系。你不可避免地需要两者吗?是的,有时这是必要的,因为它们不能解决同一个问题。例如,资产可能通过其具体模型之一
GuestPost
MemberPost
属于常规模型,例如
User
(对于化身)和STI模型,例如
Post
。STI反映了
Post
模型的“专业化”。它不能解决另一个模型-
资产
-需要反映与帖子以及系统中其他模型的某种关系(多态关系)这一事实。