我继承了一些遗留的Rails代码,这些代码在标准的多态关联周围有变通办法。这些代码过去一直工作到Rails 5。现在我试图升级到Rails 6. 1,它们坏了,我不知道如何修复它们。
**问题:**我们有以下2个表:
- 职位
- 标识符
- 正文
- ...
- 注解
- 标识符
- 可注解标识
- 可注解类型
- ...
帖子有3种类型的评论-
1.管理员注解
1.匿名评论
1.用户注解
我们将其建模为多态关系,如下所示:
第一个
使用此设置,我可以通过执行以下操作获取所有注解-
p = Post.find(123)
p.comments
或按特定类型的用户获取注解-
p = Post.find(123)
p.user_comments
p.anonymous_comments
在rails 6.1中,此设置不起作用。当尝试运行rails console
时,它失败并显示错误:
在“Assert有效密钥中的块”中:未知密钥::foreign_type。有效键为::类名,:匿名类,:主键,:外键,:从属,:验证,:反转,:严格加载,:自动保存,:添加前,:添加后,:删除前,:删除后,:扩展,:计数器缓存,:连接表,:索引错误,:确保所有者为(参数错误)
在网上寻找潜在的答案后,我能得到的最接近的答案是在每个关联中添加as: :commentable
,如-
has_many :user_comments, -> { where commentable_type: "UserComment" },
class_name: 'Comment', foreign_key: :commentable_id,
foreign_type: :commentable_type, dependent: :destroy, inverse_of: :post, as: :commentable
但这并不能得到正确的结果集。它生成的sql如下所示-
SELECT注解.* FROM注解WHERE注解.可注解标识= 123 AND注解.可注解类型= 'Post' AND注解.可注解类型= 'UserComment'
如果没有as: :commentable
,它将生成如下SQL:
SELECT注解.* FROM注解WHERE注解.可注解标识= 123 AND注解.可注解类型= '用户注解'
我有点迷路了,希望能得到任何帮助!
谢谢你!
2条答案
按热度按时间n53p2ov01#
编辑仔细阅读文档后,这应该适用于
has_one
关联类型,而不适用于has_many
Rails 6.1增加了Delegated Types,可以用来实现你想要的。
请尝试以下操作
第一个
c3frrgcw2#
这看起来像是一个非常混乱和误导的尝试,试图将单表继承和多态关联组合在一起,而不了解两者是如何工作的,我怀疑代码实际上是按照早期版本的预期工作的。
短期内
在STI设置中,您使用类型继承列(默认类型)来指定ActiveRecord在从数据库检索行时加载的类。这意味着您的
comments
表应该有一个名为type
的字符串列,其中包含UserComment
和AdminComment
之类的值。当您设置指向STI模型的多个关联时,应在表的
type
列上设置条件,而不是commentable_type
:第一个
多态关联
多态关联实际上只是一个肮脏的欺骗,以绕过对象关系障碍不匹配问题。通过使用一个整数列和一个varchar列,你可以创建一个指向任何表的单个关联-例如,这将是附加评论到帖子,视频,图片,甚至其他评论。这是
commentable_type
列实际上应该包含的内容。要将上一个示例中的关联更改为多态,只需添加
as:
选项,告诉Rails要查找的belongs_to
关联:否则,它只会假设您正在另一端查找名为 post 的关联-
as:
告诉ActiveRecord这是一个多态关联:一个
您不必配置
foreign_key
、foreign_type
或class_name
选项(这个选项完全错误),因为它们都可以从名称中派生出来。